diff options
132 files changed, 1117 insertions, 510 deletions
| diff --git a/api/current.txt b/api/current.txt index 21ee1f11b493..f380cf94836d 100644 --- a/api/current.txt +++ b/api/current.txt @@ -709,6 +709,7 @@ package android {      field public static final int overScrollFooter = 16843459; // 0x10102c3      field public static final int overScrollHeader = 16843458; // 0x10102c2      field public static final int overScrollMode = 16843457; // 0x10102c1 +    field public static final int overridesImplicitlyEnabledSubtype = 16843696; // 0x10103b0      field public static final int packageNames = 16843649; // 0x1010381      field public static final int padding = 16842965; // 0x10100d5      field public static final int paddingBottom = 16842969; // 0x10100d9 @@ -10668,7 +10669,7 @@ package android.media {      method public void setAuxEffectSendLevel(float);      method public void setDataSource(android.content.Context, android.net.Uri) throws java.io.IOException, java.lang.IllegalArgumentException, java.lang.IllegalStateException, java.lang.SecurityException;      method public void setDataSource(android.content.Context, android.net.Uri, java.util.Map<java.lang.String, java.lang.String>) throws java.io.IOException, java.lang.IllegalArgumentException, java.lang.IllegalStateException, java.lang.SecurityException; -    method public void setDataSource(java.lang.String) throws java.io.IOException, java.lang.IllegalArgumentException, java.lang.IllegalStateException; +    method public void setDataSource(java.lang.String) throws java.io.IOException, java.lang.IllegalArgumentException, java.lang.IllegalStateException, java.lang.SecurityException;      method public void setDataSource(java.io.FileDescriptor) throws java.io.IOException, java.lang.IllegalArgumentException, java.lang.IllegalStateException;      method public void setDataSource(java.io.FileDescriptor, long, long) throws java.io.IOException, java.lang.IllegalArgumentException, java.lang.IllegalStateException;      method public void setDisplay(android.view.SurfaceHolder); @@ -16774,7 +16775,7 @@ package android.provider {      field public static final android.net.Uri CONTENT_URI;    } -  public final class LiveFolders implements android.provider.BaseColumns { +  public final deprecated class LiveFolders implements android.provider.BaseColumns {      field public static final java.lang.String ACTION_CREATE_LIVE_FOLDER = "android.intent.action.CREATE_LIVE_FOLDER";      field public static final java.lang.String DESCRIPTION = "description";      field public static final int DISPLAY_MODE_GRID = 1; // 0x1 @@ -18463,7 +18464,7 @@ package android.service.textservice {      field public static final java.lang.String SERVICE_INTERFACE = "android.service.textservice.SpellCheckerService";    } -  public abstract class SpellCheckerService.Session { +  public static abstract class SpellCheckerService.Session {      ctor public SpellCheckerService.Session();      method public android.os.Bundle getBundle();      method public java.lang.String getLocale(); @@ -24486,7 +24487,7 @@ package android.view.inputmethod {      method public boolean isWatchingCursor(android.view.View);      method public void restartInput(android.view.View);      method public void sendAppPrivateCommand(android.view.View, java.lang.String, android.os.Bundle); -    method public boolean setAdditionalInputMethodSubtypes(java.lang.String, android.view.inputmethod.InputMethodSubtype[]); +    method public void setAdditionalInputMethodSubtypes(java.lang.String, android.view.inputmethod.InputMethodSubtype[]);      method public boolean setCurrentInputMethodSubtype(android.view.inputmethod.InputMethodSubtype);      method public void setInputMethod(android.os.IBinder, java.lang.String);      method public void setInputMethodAndSubtype(android.os.IBinder, java.lang.String, android.view.inputmethod.InputMethodSubtype); @@ -24531,8 +24532,7 @@ package android.view.inputmethod {    }    public final class InputMethodSubtype implements android.os.Parcelable { -    ctor public InputMethodSubtype(int, int, java.lang.String, java.lang.String, java.lang.String); -    ctor public InputMethodSubtype(int, int, java.lang.String, java.lang.String, java.lang.String, boolean); +    ctor public InputMethodSubtype(int, int, java.lang.String, java.lang.String, java.lang.String, boolean, boolean);      method public boolean containsExtraValueKey(java.lang.String);      method public int describeContents();      method public java.lang.CharSequence getDisplayName(android.content.Context, java.lang.String, android.content.pm.ApplicationInfo); @@ -24543,6 +24543,7 @@ package android.view.inputmethod {      method public java.lang.String getMode();      method public int getNameResId();      method public boolean isAuxiliary(); +    method public boolean overridesImplicitlyEnabledSubtype();      method public void writeToParcel(android.os.Parcel, int);      field public static final android.os.Parcelable.Creator CREATOR;    } diff --git a/cmds/stagefright/stream.cpp b/cmds/stagefright/stream.cpp index aa3bc03bae4d..b13236a3569c 100644 --- a/cmds/stagefright/stream.cpp +++ b/cmds/stagefright/stream.cpp @@ -357,9 +357,9 @@ int main(int argc, char **argv) {      }      sp<IMediaPlayer> player = -        service->create(getpid(), client, source, 0); +        service->create(getpid(), client, 0); -    if (player != NULL) { +    if (player != NULL && player->setDataSource(source) == NO_ERROR) {          player->setVideoSurface(surface);          player->start(); diff --git a/core/java/android/content/SyncManager.java b/core/java/android/content/SyncManager.java index 496da41c8bc0..ef6e1312a5f9 100644 --- a/core/java/android/content/SyncManager.java +++ b/core/java/android/content/SyncManager.java @@ -191,6 +191,12 @@ public class SyncManager implements OnAccountsUpdateListener {      private static final long SYNC_ALARM_TIMEOUT_MIN = 30 * 1000; // 30 seconds      private static final long SYNC_ALARM_TIMEOUT_MAX = 2 * 60 * 60 * 1000; // two hours +    /** +     * The amount of time to wait after attempting a bind before canceling a sync and disabling +     * the sync adapter +     */ +    public static final long BIND_TIMEOUT_MS = 30 * 1000; +      public void onAccountsUpdated(Account[] accounts) {          // remember if this was the first time this was called after an update          final boolean justBootedUp = mAccounts == INITIAL_ACCOUNTS_ARRAY; @@ -1068,6 +1074,9 @@ public class SyncManager implements OnAccountsUpdateListener {              pw.print(" - ");              pw.print(activeSyncContext.mSyncOperation.dump(false));              pw.println(); +            if (activeSyncContext.mSyncAdapter == null) { +                pw.println("   **** Waiting for onServiceConnected ****"); +            }          }          synchronized (mSyncQueue) { @@ -1424,6 +1433,7 @@ public class SyncManager implements OnAccountsUpdateListener {          public void handleMessage(Message msg) {              long earliestFuturePollTime = Long.MAX_VALUE;              long nextPendingSyncTime = Long.MAX_VALUE; +            long nextBindTimeoutTime = Long.MAX_VALUE;              // Setting the value here instead of a method because we want the dumpsys logs              // to have the most recent value used. @@ -1431,6 +1441,7 @@ public class SyncManager implements OnAccountsUpdateListener {                  waitUntilReadyToRun();                  mDataConnectionIsConnected = readDataConnectionState();                  mSyncManagerWakeLock.acquire(); +                nextBindTimeoutTime = auditRunningSyncsForStuckBindsLocked();                  // Always do this first so that we be sure that any periodic syncs that                  // are ready to run have been converted into pending syncs. This allows the                  // logic that considers the next steps to take based on the set of pending syncs @@ -1532,6 +1543,7 @@ public class SyncManager implements OnAccountsUpdateListener {                          break;                  }              } finally { +                nextPendingSyncTime = Math.min(nextBindTimeoutTime, nextPendingSyncTime);                  manageSyncNotificationLocked();                  manageSyncAlarmLocked(earliestFuturePollTime, nextPendingSyncTime);                  mSyncTimeTracker.update(); @@ -1540,6 +1552,36 @@ public class SyncManager implements OnAccountsUpdateListener {          }          /** +         * Looks to see if any of the active syncs have been waiting for a bind for too long, +         * and if so the sync is canceled and the sync adapter is disabled for that account. +         * @return the earliest time that an active sync can have waited too long to bind, +         * relative to {@link android.os.SystemClock#elapsedRealtime()}. +         */ +        private long auditRunningSyncsForStuckBindsLocked() { +            final long now = SystemClock.elapsedRealtime(); +            long oldest = Long.MAX_VALUE; +            for (ActiveSyncContext active : mActiveSyncContexts) { +                if (active.mSyncAdapter == null) { +                    final long timeoutTime = active.mStartTime + BIND_TIMEOUT_MS; +                    if (timeoutTime < now) { +                        Log.w(TAG, "canceling long-running bind and disabling sync for " +                                + active.mSyncOperation.account + ", authority " +                                + active.mSyncOperation.authority); +                        runSyncFinishedOrCanceledLocked(null, active); +                        ContentResolver.setIsSyncable(active.mSyncOperation.account, +                                active.mSyncOperation.authority, 0); +                    } else { +                        if (oldest > timeoutTime) { +                            oldest = timeoutTime; +                        } +                    } +                } +            } + +            return oldest; +        } + +        /**           * Turn any periodic sync operations that are ready to run into pending sync operations.           * @return the desired start time of the earliest future  periodic sync operation,           * in milliseconds since boot @@ -1819,13 +1861,17 @@ public class SyncManager implements OnAccountsUpdateListener {                  synchronized (mSyncQueue){                      mSyncQueue.remove(candidate);                  } -                dispatchSyncOperation(candidate); +                ActiveSyncContext newSyncContext = dispatchSyncOperation(candidate); +                if (newSyncContext != null) { +                    nextReadyToRunTime = Math.min(nextReadyToRunTime, +                            newSyncContext.mStartTime + BIND_TIMEOUT_MS); +                }              }              return nextReadyToRunTime;       } -        private boolean dispatchSyncOperation(SyncOperation op) { +        private ActiveSyncContext dispatchSyncOperation(SyncOperation op) {              if (Log.isLoggable(TAG, Log.VERBOSE)) {                  Log.v(TAG, "dispatchSyncOperation: we are going to sync " + op);                  Log.v(TAG, "num active syncs: " + mActiveSyncContexts.size()); @@ -1842,7 +1888,7 @@ public class SyncManager implements OnAccountsUpdateListener {                  Log.d(TAG, "can't find a sync adapter for " + syncAdapterType                          + ", removing settings for it");                  mSyncStorageEngine.removeAuthority(op.account, op.authority); -                return false; +                return null;              }              ActiveSyncContext activeSyncContext = @@ -1855,10 +1901,10 @@ public class SyncManager implements OnAccountsUpdateListener {              if (!activeSyncContext.bindToSyncAdapter(syncAdapterInfo)) {                  Log.e(TAG, "Bind attempt failed to " + syncAdapterInfo);                  closeActiveSyncContext(activeSyncContext); -                return false; +                return null;              } -            return true; +            return activeSyncContext;          }          private void runBoundToSyncAdapter(final ActiveSyncContext activeSyncContext, diff --git a/core/java/android/net/NetworkStats.java b/core/java/android/net/NetworkStats.java index e5f32735b00a..3918cfdfb485 100644 --- a/core/java/android/net/NetworkStats.java +++ b/core/java/android/net/NetworkStats.java @@ -320,15 +320,36 @@ public class NetworkStats implements Parcelable {       * checking if a {@link #subtract(NetworkStats)} delta passes a threshold.       */      public long getTotalBytes() { -        long totalBytes = 0; +        final Entry entry = getTotal(null); +        return entry.rxBytes + entry.txBytes; +    } + +    /** +     * Return total of all fields represented by this snapshot object. +     */ +    public Entry getTotal(Entry recycle) { +        final Entry entry = recycle != null ? recycle : new Entry(); + +        entry.iface = IFACE_ALL; +        entry.uid = UID_ALL; +        entry.set = SET_ALL; +        entry.tag = TAG_NONE; +        entry.rxBytes = 0; +        entry.rxPackets = 0; +        entry.txBytes = 0; +        entry.txPackets = 0; +          for (int i = 0; i < size; i++) {              // skip specific tags, since already counted in TAG_NONE              if (tag[i] != TAG_NONE) continue; -            totalBytes += rxBytes[i]; -            totalBytes += txBytes[i]; +            entry.rxBytes += rxBytes[i]; +            entry.rxPackets += rxPackets[i]; +            entry.txBytes += txBytes[i]; +            entry.txPackets += txPackets[i]; +            entry.operations += operations[i];          } -        return totalBytes; +        return entry;      }      /** diff --git a/core/java/android/nfc/NfcActivityManager.java b/core/java/android/nfc/NfcActivityManager.java index 3cc682035612..da878d4f2228 100644 --- a/core/java/android/nfc/NfcActivityManager.java +++ b/core/java/android/nfc/NfcActivityManager.java @@ -20,7 +20,7 @@ import android.app.Activity;  import android.os.RemoteException;  import android.util.Log; -import java.util.HashMap; +import java.util.WeakHashMap;  /**   * Manages NFC API's that are coupled to the life-cycle of an Activity. @@ -38,7 +38,7 @@ public final class NfcActivityManager extends INdefPushCallback.Stub {      static final Boolean DBG = false;      final NfcAdapter mAdapter; -    final HashMap<Activity, NfcActivityState> mNfcState;  // contents protected by this +    final WeakHashMap<Activity, NfcActivityState> mNfcState;  // contents protected by this      final NfcEvent mDefaultEvent;  // can re-use one NfcEvent because it just contains adapter      /** @@ -60,7 +60,7 @@ public final class NfcActivityManager extends INdefPushCallback.Stub {      public NfcActivityManager(NfcAdapter adapter) {          mAdapter = adapter; -        mNfcState = new HashMap<Activity, NfcActivityState>(); +        mNfcState = new WeakHashMap<Activity, NfcActivityState>();          mDefaultEvent = new NfcEvent(mAdapter);      } @@ -88,6 +88,13 @@ public final class NfcActivityManager extends INdefPushCallback.Stub {          }      } +    /** +     * onDestroy hook from fragment attached to activity +     */ +    public void onDestroy(Activity activity) { +        mNfcState.remove(activity); +    } +      public synchronized void setNdefPushMessage(Activity activity, NdefMessage message) {          NfcActivityState state = getOrCreateState(activity, message != null);          if (state == null || state.ndefMessage == message) { @@ -214,4 +221,5 @@ public final class NfcActivityManager extends INdefPushCallback.Stub {              callback.onNdefPushComplete(mDefaultEvent);          }      } +  } diff --git a/core/java/android/nfc/NfcFragment.java b/core/java/android/nfc/NfcFragment.java index c48859b1c6e7..17278dc04cc7 100644 --- a/core/java/android/nfc/NfcFragment.java +++ b/core/java/android/nfc/NfcFragment.java @@ -80,4 +80,14 @@ public final class NfcFragment extends Fragment {              sNfcActivityManager.onPause(getActivity());          }      } + +    @Override +    public void onDestroy() { +        super.onDestroy(); +        if (sNfcActivityManager != null) { +            sNfcActivityManager.onDestroy(getActivity()); +        } +    } + +  } diff --git a/core/java/android/provider/LiveFolders.java b/core/java/android/provider/LiveFolders.java index 7856bab016cb..cf8ad46a832f 100644 --- a/core/java/android/provider/LiveFolders.java +++ b/core/java/android/provider/LiveFolders.java @@ -162,7 +162,17 @@ import android.annotation.SdkConstant;   *     </tr>   *     </tbody>   * </table> + *  + * @deprecated Live folders are no longer supported by Android.  These have been + * replaced by the new + * <a href="{@docRoot}guide/topics/appwidgets/index.html#collections">AppWidget Collection</a> + * APIs introduced in {@link android.os.Build.VERSION_CODES#HONEYCOMB}.  These provide + * all of the features of live folders plus many more.  The use of live folders is greatly + * discouraged because of security issues they introduce -- publishing a live folder requires + * making all data show for the live folder available to all applications with no + * permissions protecting it.   */ +@Deprecated  public final class LiveFolders implements BaseColumns {      /**       * <p>Content provider column.</p> diff --git a/core/java/android/service/textservice/SpellCheckerService.java b/core/java/android/service/textservice/SpellCheckerService.java index 3e2e38eb004b..b96099e52b39 100644 --- a/core/java/android/service/textservice/SpellCheckerService.java +++ b/core/java/android/service/textservice/SpellCheckerService.java @@ -66,7 +66,7 @@ public abstract class SpellCheckerService extends Service {      /**       * This abstract class should be overridden by a concrete implementation of a spell checker.       */ -    public abstract class Session { +    public static abstract class Session {          private InternalISpellCheckerSession mInternalSession;          /** diff --git a/core/java/android/text/method/ArrowKeyMovementMethod.java b/core/java/android/text/method/ArrowKeyMovementMethod.java index fe965651f70e..b8728ee30d22 100644 --- a/core/java/android/text/method/ArrowKeyMovementMethod.java +++ b/core/java/android/text/method/ArrowKeyMovementMethod.java @@ -232,8 +232,7 @@ public class ArrowKeyMovementMethod extends BaseMovementMethod implements Moveme          if (widget.isFocused() && !widget.didTouchFocusSelect()) {              if (action == MotionEvent.ACTION_DOWN) { -              boolean cap = isSelecting(buffer); -              if (cap) { +              if (isSelecting(buffer)) {                    int offset = widget.getOffsetForPosition(event.getX(), event.getY());                    buffer.setSpan(LAST_TAP_DOWN, offset, offset, Spannable.SPAN_POINT_POINT); @@ -245,9 +244,7 @@ public class ArrowKeyMovementMethod extends BaseMovementMethod implements Moveme                    widget.getParent().requestDisallowInterceptTouchEvent(true);                }              } else if (action == MotionEvent.ACTION_MOVE) { -                boolean cap = isSelecting(buffer); - -                if (cap && handled) { +                if (isSelecting(buffer) && handled) {                      // Before selecting, make sure we've moved out of the "slop".                      // handled will be true, if we're in select mode AND we're                      // OUT of the slop @@ -279,7 +276,7 @@ public class ArrowKeyMovementMethod extends BaseMovementMethod implements Moveme                  if (isSelecting(buffer)) {                      buffer.removeSpan(LAST_TAP_DOWN);                      Selection.extendSelection(buffer, offset); -                } else { +                } else if (!widget.shouldIgnoreActionUpEvent()) {                      Selection.setSelection(buffer, offset);                  } diff --git a/core/java/android/text/method/Touch.java b/core/java/android/text/method/Touch.java index a528044ef1fd..3f9b94563a0b 100644 --- a/core/java/android/text/method/Touch.java +++ b/core/java/android/text/method/Touch.java @@ -147,12 +147,10 @@ public class Touch {                      int nx = widget.getScrollX() + (int) dx;                      int ny = widget.getScrollY() + (int) dy; -                    int padding = widget.getTotalPaddingTop() + -                                  widget.getTotalPaddingBottom(); +                    int padding = widget.getTotalPaddingTop() + widget.getTotalPaddingBottom();                      Layout layout = widget.getLayout(); -                    ny = Math.min(ny, layout.getHeight() - (widget.getHeight() - -                                                            padding)); +                    ny = Math.min(ny, layout.getHeight() - (widget.getHeight() - padding));                      ny = Math.max(ny, 0);                      int oldX = widget.getScrollX(); @@ -161,8 +159,7 @@ public class Touch {                      scrollTo(widget, layout, nx, ny);                      // If we actually scrolled, then cancel the up action. -                    if (oldX != widget.getScrollX() -                            || oldY != widget.getScrollY()) { +                    if (oldX != widget.getScrollX() || oldY != widget.getScrollY()) {                          widget.cancelLongPress();                      } diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java index bb12a573b5d6..fa1d24961dda 100644 --- a/core/java/android/view/View.java +++ b/core/java/android/view/View.java @@ -9362,7 +9362,6 @@ public class View implements Drawable.Callback2, KeyEvent.Callback, Accessibilit          if (mAttachInfo != null) {              mAttachInfo.mHandler.removeMessages(AttachInfo.INVALIDATE_MSG, this); -            mAttachInfo.mHandler.removeMessages(AttachInfo.INVALIDATE_RECT_MSG, this);          }          mCurrentAnimation = null; @@ -13910,6 +13909,7 @@ public class View implements Drawable.Callback2, KeyEvent.Callback, Accessibilit                          }                          public void onReleased(InvalidateInfo element) { +                            element.target = null;                          }                      }, POOL_LIMIT)              ); diff --git a/core/java/android/view/inputmethod/InputMethodInfo.java b/core/java/android/view/inputmethod/InputMethodInfo.java index 4ec4ff9de30d..0119d0397dc4 100644 --- a/core/java/android/view/inputmethod/InputMethodInfo.java +++ b/core/java/android/view/inputmethod/InputMethodInfo.java @@ -164,7 +164,9 @@ public final class InputMethodInfo implements Parcelable {                              a.getString(com.android.internal.R.styleable                                      .InputMethod_Subtype_imeSubtypeExtraValue),                              a.getBoolean(com.android.internal.R.styleable -                                    .InputMethod_Subtype_isAuxiliary, false)); +                                    .InputMethod_Subtype_isAuxiliary, false), +                            a.getBoolean(com.android.internal.R.styleable +                                    .InputMethod_Subtype_overridesImplicitlyEnabledSubtype, false));                      mSubtypes.add(subtype);                  }              } diff --git a/core/java/android/view/inputmethod/InputMethodManager.java b/core/java/android/view/inputmethod/InputMethodManager.java index 302be57d54af..3ead9df0e3eb 100644 --- a/core/java/android/view/inputmethod/InputMethodManager.java +++ b/core/java/android/view/inputmethod/InputMethodManager.java @@ -1593,15 +1593,13 @@ public final class InputMethodManager {       * to the current implementation.)       * @param imiId Id of InputMethodInfo which additional input method subtypes will be added to.       * @param subtypes subtypes will be added as additional subtypes of the current input method. -     * @return true if the additional input method subtypes are successfully added.       */ -    public boolean setAdditionalInputMethodSubtypes(String imiId, InputMethodSubtype[] subtypes) { +    public void setAdditionalInputMethodSubtypes(String imiId, InputMethodSubtype[] subtypes) {          synchronized (mH) {              try { -                return mService.setAdditionalInputMethodSubtypes(imiId, subtypes); +                mService.setAdditionalInputMethodSubtypes(imiId, subtypes);              } catch (RemoteException e) {                  Log.w(TAG, "IME died: " + mCurId, e); -                return false;              }          }      } diff --git a/core/java/android/view/inputmethod/InputMethodSubtype.java b/core/java/android/view/inputmethod/InputMethodSubtype.java index 4a983360a897..567043223b35 100644 --- a/core/java/android/view/inputmethod/InputMethodSubtype.java +++ b/core/java/android/view/inputmethod/InputMethodSubtype.java @@ -42,6 +42,7 @@ public final class InputMethodSubtype implements Parcelable {      private static final String EXTRA_VALUE_KEY_VALUE_SEPARATOR = "=";      private final boolean mIsAuxiliary; +    private final boolean mOverridesImplicitlyEnabledSubtype;      private final int mSubtypeHashCode;      private final int mSubtypeIconResId;      private final int mSubtypeNameResId; @@ -57,10 +58,12 @@ public final class InputMethodSubtype implements Parcelable {       * @param locale The locale supported by the subtype       * @param mode The mode supported by the subtype       * @param extraValue The extra value of the subtype +     * @param isAuxiliary true when this subtype is one shot subtype. +     * @hide       */ -    public InputMethodSubtype( -            int nameId, int iconId, String locale, String mode, String extraValue) { -        this(nameId, iconId, locale, mode, extraValue, false); +    public InputMethodSubtype(int nameId, int iconId, String locale, String mode, String extraValue, +            boolean isAuxiliary) { +        this(nameId, iconId, locale, mode, extraValue, false, false);      }      /** @@ -71,17 +74,21 @@ public final class InputMethodSubtype implements Parcelable {       * @param mode The mode supported by the subtype       * @param extraValue The extra value of the subtype       * @param isAuxiliary true when this subtype is one shot subtype. +     * @param overridesImplicitlyEnabledSubtype true when this subtype should be selected by default +     * if no other subtypes are selected explicitly. Note that a subtype with this parameter being +     * true will not be shown in the subtypes list.       */      public InputMethodSubtype(int nameId, int iconId, String locale, String mode, String extraValue, -            boolean isAuxiliary) { +            boolean isAuxiliary, boolean overridesImplicitlyEnabledSubtype) {          mSubtypeNameResId = nameId;          mSubtypeIconResId = iconId;          mSubtypeLocale = locale != null ? locale : "";          mSubtypeMode = mode != null ? mode : "";          mSubtypeExtraValue = extraValue != null ? extraValue : "";          mIsAuxiliary = isAuxiliary; +        mOverridesImplicitlyEnabledSubtype = overridesImplicitlyEnabledSubtype;          mSubtypeHashCode = hashCodeInternal(mSubtypeLocale, mSubtypeMode, mSubtypeExtraValue, -                mIsAuxiliary); +                mIsAuxiliary, mOverridesImplicitlyEnabledSubtype);      }      InputMethodSubtype(Parcel source) { @@ -95,8 +102,9 @@ public final class InputMethodSubtype implements Parcelable {          s = source.readString();          mSubtypeExtraValue = s != null ? s : "";          mIsAuxiliary = (source.readInt() == 1); +        mOverridesImplicitlyEnabledSubtype = (source.readInt() == 1);          mSubtypeHashCode = hashCodeInternal(mSubtypeLocale, mSubtypeMode, mSubtypeExtraValue, -                mIsAuxiliary); +                mIsAuxiliary, mOverridesImplicitlyEnabledSubtype);      }      /** @@ -144,6 +152,14 @@ public final class InputMethodSubtype implements Parcelable {      }      /** +     * @return true when this subtype is selected by default if no other subtypes are selected +     * explicitly. Note that a subtype that returns true will not be shown in the subtypes list. +     */ +    public boolean overridesImplicitlyEnabledSubtype() { +        return mOverridesImplicitlyEnabledSubtype; +    } + +    /**       * @param context Context will be used for getting Locale and PackageManager.       * @param packageName The package name of the IME       * @param appInfo The application info of the IME @@ -242,6 +258,7 @@ public final class InputMethodSubtype implements Parcelable {          dest.writeString(mSubtypeMode);          dest.writeString(mSubtypeExtraValue);          dest.writeInt(mIsAuxiliary ? 1 : 0); +        dest.writeInt(mOverridesImplicitlyEnabledSubtype ? 1 : 0);      }      public static final Parcelable.Creator<InputMethodSubtype> CREATOR @@ -274,8 +291,9 @@ public final class InputMethodSubtype implements Parcelable {      }      private static int hashCodeInternal(String locale, String mode, String extraValue, -            boolean isAuxiliary) { -        return Arrays.hashCode(new Object[] {locale, mode, extraValue, isAuxiliary}); +            boolean isAuxiliary, boolean overridesImplicitlyEnabledSubtype) { +        return Arrays.hashCode(new Object[] {locale, mode, extraValue, isAuxiliary, +                overridesImplicitlyEnabledSubtype});      }      /** diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java index 2e7f923092f9..64fbae6fbd4c 100644 --- a/core/java/android/webkit/WebView.java +++ b/core/java/android/webkit/WebView.java @@ -2346,6 +2346,14 @@ public class WebView extends AbsoluteLayout      }      /** +     * Return the reading level scale of the WebView +     * @return The reading level scale. +     */ +    /*package*/ float getReadingLevelScale() { +        return mZoomManager.getReadingLevelScale(); +    } + +    /**       * Set the initial scale for the WebView. 0 means default. If       * {@link WebSettings#getUseWideViewPort()} is true, it zooms out all the       * way. Otherwise it starts with 100%. If initial scale is greater than 0, diff --git a/core/java/android/webkit/WebViewCore.java b/core/java/android/webkit/WebViewCore.java index 73a30c4b9855..c61bd4868dce 100644 --- a/core/java/android/webkit/WebViewCore.java +++ b/core/java/android/webkit/WebViewCore.java @@ -538,6 +538,8 @@ public final class WebViewCore {      private native void nativeSendListBoxChoice(int choice); +    private native void nativeCloseIdleConnections(); +      /*  Tell webkit what its width and height are, for the purposes          of layout/line-breaking. These coordinates are in document space,          which is the same as View coords unless we have zoomed the document @@ -1262,6 +1264,8 @@ public final class WebViewCore {                              if (!JniUtil.useChromiumHttpStack()) {                                  WebViewWorker.getHandler().sendEmptyMessage(                                          WebViewWorker.MSG_PAUSE_CACHE_TRANSACTION); +                            } else { +                                nativeCloseIdleConnections();                              }                              break; @@ -2456,7 +2460,7 @@ public final class WebViewCore {                      if (mSettings.isNarrowColumnLayout()) {                          // In case of automatic text reflow in fixed view port mode.                          mInitialViewState.mTextWrapScale = -                                ZoomManager.computeReadingLevelScale(data.mScale); +                                mWebView.getReadingLevelScale();                      }                  } else {                      // Scale is given such as when page is restored, use it. diff --git a/core/java/android/webkit/ZoomManager.java b/core/java/android/webkit/ZoomManager.java index 2bcb0202955f..0bfb6683452b 100644 --- a/core/java/android/webkit/ZoomManager.java +++ b/core/java/android/webkit/ZoomManager.java @@ -58,13 +58,6 @@ class ZoomManager {      private ZoomControlExternal mExternalZoomControl;      /* -     * For large screen devices, the defaultScale usually set to 1.0 and -     * equal to the overview scale, to differentiate the zoom level for double tapping, -     * a default reading level scale is used. -     */ -    private static final float DEFAULT_READING_LEVEL_SCALE = 1.5f; - -    /*       * The scale factors that determine the upper and lower bounds for the       * default zoom scale.       */ @@ -151,6 +144,19 @@ class ZoomManager {      private float mDefaultScale;      private float mInvDefaultScale; +    /* +     * The scale factor that is used to determine the zoom level for reading text. +     * The value is initially set to equal the display density. +     * TODO: Support changing this in WebSettings +     */ +    private float mReadingLevelScale; + +    /* +     * The scale factor that is used as the minimum increment when going from +     * overview to reading level on a double tap. +     */ +    private static float MIN_DOUBLE_TAP_SCALE_INCREMENT = 0.5f; +      // the current computed zoom scale and its inverse.      private float mActualScale;      private float mInvActualScale; @@ -230,6 +236,7 @@ class ZoomManager {          setDefaultZoomScale(density);          mActualScale = density;          mInvActualScale = 1 / density; +        mReadingLevelScale = density;          mTextWrapScale = density;      } @@ -304,13 +311,7 @@ class ZoomManager {      }      public final float getReadingLevelScale() { -        return computeScaleWithLimits(computeReadingLevelScale(getZoomOverviewScale())); -    } - -    /* package */ final static float computeReadingLevelScale(float scale) { -        // The reading scale is at least 0.5f apart from the input scale. -        final float MIN_SCALE_DIFF = 0.5f; -        return Math.max(scale + MIN_SCALE_DIFF, DEFAULT_READING_LEVEL_SCALE); +        return mReadingLevelScale;      }      public final float getInvDefaultScale() { @@ -652,7 +653,7 @@ class ZoomManager {          } else if (!mInZoomOverview && willScaleTriggerZoom(getZoomOverviewScale())) {              zoomToOverview();          } else { -            zoomToReadingLevel(); +            zoomToReadingLevelOrMore();          }      } @@ -683,8 +684,10 @@ class ZoomManager {              !mWebView.getSettings().getUseFixedViewport());      } -    private void zoomToReadingLevel() { -        final float readingScale = getReadingLevelScale(); +    private void zoomToReadingLevelOrMore() { +        final float zoomScale = Math.max(getReadingLevelScale(), +                mActualScale + MIN_DOUBLE_TAP_SCALE_INCREMENT); +          int left = mWebView.nativeGetBlockLeftEdge(mAnchorX, mAnchorY, mActualScale);          if (left != WebView.NO_LEFTEDGE) {              // add a 5pt padding to the left edge. @@ -693,13 +696,13 @@ class ZoomManager {              // Re-calculate the zoom center so that the new scroll x will be              // on the left edge.              if (viewLeft > 0) { -                mZoomCenterX = viewLeft * readingScale / (readingScale - mActualScale); +                mZoomCenterX = viewLeft * zoomScale / (zoomScale - mActualScale);              } else {                  mWebView.scrollBy(viewLeft, 0);                  mZoomCenterX = 0;              }          } -        startZoomAnimation(readingScale, +        startZoomAnimation(zoomScale,              !mWebView.getSettings().getUseFixedViewport());      } diff --git a/core/java/android/widget/AdapterView.java b/core/java/android/widget/AdapterView.java index f267458c3524..4ba604d5adf6 100644 --- a/core/java/android/widget/AdapterView.java +++ b/core/java/android/widget/AdapterView.java @@ -926,6 +926,8 @@ public abstract class AdapterView<T extends Adapter> extends ViewGroup {          }          event.setItemCount(getCount());          event.setCurrentItemIndex(getSelectedItemPosition()); +        event.setFromIndex(mFirstPosition); +        event.setToIndex(mFirstPosition + getChildCount());      }      @Override diff --git a/core/java/android/widget/DatePicker.java b/core/java/android/widget/DatePicker.java index 481228325cdd..3b67f4470957 100644 --- a/core/java/android/widget/DatePicker.java +++ b/core/java/android/widget/DatePicker.java @@ -30,6 +30,7 @@ import android.util.Log;  import android.util.SparseArray;  import android.view.LayoutInflater;  import android.view.accessibility.AccessibilityEvent; +import android.view.accessibility.AccessibilityManager;  import android.widget.NumberPicker.OnValueChangeListener;  import com.android.internal.R; @@ -264,6 +265,11 @@ public class DatePicker extends FrameLayout {          // re-order the number spinners to match the current date format          reorderSpinners(); + +        // set content descriptions +        if (AccessibilityManager.getInstance(mContext).isEnabled()) { +            setContentDescriptions(); +        }      }      /** @@ -357,11 +363,16 @@ public class DatePicker extends FrameLayout {      }      @Override +    public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) { +        onPopulateAccessibilityEvent(event); +        return true; +    } + +    @Override      public void onPopulateAccessibilityEvent(AccessibilityEvent event) {          super.onPopulateAccessibilityEvent(event); -        final int flags = DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_SHOW_WEEKDAY -                | DateUtils.FORMAT_SHOW_YEAR; +        final int flags = DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_SHOW_YEAR;          String selectedDateUtterance = DateUtils.formatDateTime(mContext,                  mCurrentDate.getTimeInMillis(), flags);          event.getText().add(selectedDateUtterance); @@ -709,5 +720,22 @@ public class DatePicker extends FrameLayout {              }          };      } -} +    private void setContentDescriptions() { +        // Day +        String text = mContext.getString(R.string.date_picker_increment_day_button); +        mDaySpinner.findViewById(R.id.increment).setContentDescription(text); +        text = mContext.getString(R.string.date_picker_decrement_day_button); +        mDaySpinner.findViewById(R.id.decrement).setContentDescription(text); +        // Month +        text = mContext.getString(R.string.date_picker_increment_month_button); +        mMonthSpinner.findViewById(R.id.increment).setContentDescription(text); +        text = mContext.getString(R.string.date_picker_decrement_month_button); +        mMonthSpinner.findViewById(R.id.decrement).setContentDescription(text); +        // Year +        text = mContext.getString(R.string.date_picker_increment_year_button); +        mYearSpinner.findViewById(R.id.increment).setContentDescription(text); +        text = mContext.getString(R.string.date_picker_decrement_year_button); +        mYearSpinner.findViewById(R.id.decrement).setContentDescription(text); +    } +} diff --git a/core/java/android/widget/NumberPicker.java b/core/java/android/widget/NumberPicker.java index 2a299bdcf00e..35e48f228fec 100644 --- a/core/java/android/widget/NumberPicker.java +++ b/core/java/android/widget/NumberPicker.java @@ -33,6 +33,7 @@ import android.graphics.Paint;  import android.graphics.Rect;  import android.graphics.Paint.Align;  import android.graphics.drawable.Drawable; +import android.os.SystemClock;  import android.text.InputFilter;  import android.text.InputType;  import android.text.Spanned; @@ -48,6 +49,8 @@ import android.view.VelocityTracker;  import android.view.View;  import android.view.ViewConfiguration;  import android.view.LayoutInflater.Filter; +import android.view.accessibility.AccessibilityEvent; +import android.view.accessibility.AccessibilityManager;  import android.view.animation.DecelerateInterpolator;  import android.view.inputmethod.InputMethodManager; @@ -471,7 +474,7 @@ public class NumberPicker extends LinearLayout {          // the fading edge effect implemented by View and we need our          // draw() method to be called. Therefore, we declare we will draw.          setWillNotDraw(false); -        setDrawSelectorWheel(false); +        setDrawScrollWheel(false);          LayoutInflater inflater = (LayoutInflater) getContext().getSystemService(                  Context.LAYOUT_INFLATER_SERVICE); @@ -561,7 +564,7 @@ public class NumberPicker extends LinearLayout {              public void onAnimationEnd(Animator animation) {                  if (!mCanceled) {                      // if canceled => we still want the wheel drawn -                    setDrawSelectorWheel(false); +                    setDrawScrollWheel(false);                  }                  mCanceled = false;                  mSelectorPaint.setAlpha(255); @@ -587,7 +590,7 @@ public class NumberPicker extends LinearLayout {              // Start with shown selector wheel and hidden controls. When made              // visible hide the selector and fade-in the controls to suggest              // fling interaction. -            setDrawSelectorWheel(true); +            setDrawScrollWheel(true);              hideInputControls();          }      } @@ -630,7 +633,7 @@ public class NumberPicker extends LinearLayout {                          || (!mDecrementButton.isShown()                                  && isEventInViewHitRect(event, mDecrementButton))) {                      mAdjustScrollerOnUpEvent = false; -                    setDrawSelectorWheel(true); +                    setDrawScrollWheel(true);                      hideInputControls();                      return true;                  } @@ -641,7 +644,7 @@ public class NumberPicker extends LinearLayout {                  if (deltaDownY > mTouchSlop) {                      mBeginEditOnUpEvent = false;                      onScrollStateChange(OnScrollListener.SCROLL_STATE_TOUCH_SCROLL); -                    setDrawSelectorWheel(true); +                    setDrawScrollWheel(true);                      hideInputControls();                      return true;                  } @@ -678,7 +681,7 @@ public class NumberPicker extends LinearLayout {                  break;              case MotionEvent.ACTION_UP:                  if (mBeginEditOnUpEvent) { -                    setDrawSelectorWheel(false); +                    setDrawScrollWheel(false);                      showInputControls(mShowInputControlsAnimimationDuration);                      mInputText.requestFocus();                      InputMethodManager imm = (InputMethodManager) getContext().getSystemService( @@ -1135,6 +1138,12 @@ public class NumberPicker extends LinearLayout {          }      } +    @Override +    public void sendAccessibilityEvent(int eventType) { +        // Do not send accessibility events - we want the user to +        // perceive this widget as several controls rather as a whole. +    } +      /**       * Resets the selector indices and clear the cached       * string representation of these indices. @@ -1192,10 +1201,19 @@ public class NumberPicker extends LinearLayout {      /**       * Sets if to <code>drawSelectionWheel</code>.       */ -    private void setDrawSelectorWheel(boolean drawSelectorWheel) { +    private void setDrawScrollWheel(boolean drawSelectorWheel) {          mDrawSelectorWheel = drawSelectorWheel;          // do not fade if the selector wheel not shown          setVerticalFadingEdgeEnabled(drawSelectorWheel); + +        if (mFlingable && mDrawSelectorWheel +                && AccessibilityManager.getInstance(mContext).isEnabled()) { +            AccessibilityManager.getInstance(mContext).interrupt(); +            String text = mContext.getString(R.string.number_picker_increment_scroll_action); +            mInputText.setContentDescription(text); +            mInputText.sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_SELECTED); +            mInputText.setContentDescription(null); +        }      }      private void initializeScrollWheel() { @@ -1429,6 +1447,12 @@ public class NumberPicker extends LinearLayout {              mInputText.setText(mDisplayedValues[mValue - mMinValue]);          }          mInputText.setSelection(mInputText.getText().length()); + +        if (mFlingable && AccessibilityManager.getInstance(mContext).isEnabled()) { +            String text = mContext.getString(R.string.number_picker_increment_scroll_mode, +                    mInputText.getText()); +            mInputText.setContentDescription(text); +        }      }      /** diff --git a/core/java/android/widget/Switch.java b/core/java/android/widget/Switch.java index 4fcb358830db..02c9d0353265 100644 --- a/core/java/android/widget/Switch.java +++ b/core/java/android/widget/Switch.java @@ -161,6 +161,7 @@ public class Switch extends CompoundButton {          mMinFlingVelocity = config.getScaledMinimumFlingVelocity();          // Refresh display with current params +        refreshDrawableState();          setChecked(isChecked());      } @@ -632,8 +633,9 @@ public class Switch extends CompoundButton {          int[] myDrawableState = getDrawableState();          // Set the state of the Drawable -        mThumbDrawable.setState(myDrawableState); -        mTrackDrawable.setState(myDrawableState); +        // Drawable may be null when checked state is set from XML, from super constructor +        if (mThumbDrawable != null) mThumbDrawable.setState(myDrawableState); +        if (mTrackDrawable != null) mTrackDrawable.setState(myDrawableState);          invalidate();      } diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java index 1c41cc87c059..126274745b4e 100644 --- a/core/java/android/widget/TextView.java +++ b/core/java/android/widget/TextView.java @@ -8245,10 +8245,10 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener              return superResult;          } -        final boolean touchIsFinished = action == MotionEvent.ACTION_UP && !mIgnoreActionUpEvent && -                isFocused(); +        final boolean touchIsFinished = (action == MotionEvent.ACTION_UP) && +                !shouldIgnoreActionUpEvent() && isFocused(); -        if ((mMovement != null || onCheckIsTextEditor()) && isEnabled() +         if ((mMovement != null || onCheckIsTextEditor()) && isEnabled()                  && mText instanceof Spannable && mLayout != null) {              boolean handled = false; @@ -8256,9 +8256,10 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener                  handled |= mMovement.onTouchEvent(this, (Spannable) mText, event);              } -            if (mLinksClickable && mAutoLinkMask != 0 && mTextIsSelectable && touchIsFinished) { +            if (touchIsFinished && mLinksClickable && mAutoLinkMask != 0 && mTextIsSelectable) {                  // The LinkMovementMethod which should handle taps on links has not been installed -                // to support text selection. We reproduce its behavior here to open links. +                // on non editable text that support text selection. +                // We reproduce its behavior here to open links for these.                  ClickableSpan[] links = ((Spannable) mText).getSpans(getSelectionStart(),                          getSelectionEnd(), ClickableSpan.class); @@ -8268,7 +8269,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener                  }              } -            if ((isTextEditable() || mTextIsSelectable) && touchIsFinished) { +            if (touchIsFinished && (isTextEditable() || mTextIsSelectable)) {                  // Show the IME, except when selecting in read-only text.                  final InputMethodManager imm = InputMethodManager.peekInstance();                  if (imm != null) { @@ -8279,16 +8280,12 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener                  }                  boolean selectAllGotFocus = mSelectAllOnFocus && didTouchFocusSelect(); -                if (!selectAllGotFocus && hasSelection()) { -                    startSelectionActionMode(); -                } else { -                    hideControllers(); -                    if (!selectAllGotFocus && mText.length() > 0) { -                        if (isCursorInsideEasyCorrectionSpan()) { -                            showSuggestions(); -                        } else if (hasInsertionController()) { -                            getInsertionController().show(); -                        } +                hideControllers(); +                if (!selectAllGotFocus && mText.length() > 0) { +                    if (isCursorInsideEasyCorrectionSpan()) { +                        showSuggestions(); +                    } else if (hasInsertionController()) { +                        getInsertionController().show();                      }                  } @@ -8400,7 +8397,18 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener          super.cancelLongPress();          mIgnoreActionUpEvent = true;      } -     + +    /** +     * This method is only valid during a touch event. +     * +     * @return true when the ACTION_UP event should be ignored, false otherwise. +     * +     * @hide +     */ +    public boolean shouldIgnoreActionUpEvent() { +        return mIgnoreActionUpEvent; +    } +      @Override      public boolean onTrackballEvent(MotionEvent event) {          if (mMovement != null && mText instanceof Spannable && diff --git a/core/java/android/widget/TimePicker.java b/core/java/android/widget/TimePicker.java index 05474382613d..23502299c7c1 100644 --- a/core/java/android/widget/TimePicker.java +++ b/core/java/android/widget/TimePicker.java @@ -29,6 +29,7 @@ import android.util.AttributeSet;  import android.view.LayoutInflater;  import android.view.View;  import android.view.accessibility.AccessibilityEvent; +import android.view.accessibility.AccessibilityManager;  import android.widget.NumberPicker.OnValueChangeListener;  import java.text.DateFormatSymbols; @@ -227,6 +228,11 @@ public class TimePicker extends FrameLayout {          if (!isEnabled()) {              setEnabled(false);          } + +        // set the content descriptions +        if (AccessibilityManager.getInstance(mContext).isEnabled()) { +            setContentDescriptions(); +        }      }      @Override @@ -433,6 +439,12 @@ public class TimePicker extends FrameLayout {      }      @Override +    public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) { +        onPopulateAccessibilityEvent(event); +        return true; +    } + +    @Override      public void onPopulateAccessibilityEvent(AccessibilityEvent event) {          super.onPopulateAccessibilityEvent(event); @@ -487,4 +499,22 @@ public class TimePicker extends FrameLayout {              mOnTimeChangedListener.onTimeChanged(this, getCurrentHour(), getCurrentMinute());          }      } + +    private void setContentDescriptions() { +        // Minute +        String text = mContext.getString(R.string.time_picker_increment_minute_button); +        mMinuteSpinner.findViewById(R.id.increment).setContentDescription(text); +        text = mContext.getString(R.string.time_picker_decrement_minute_button); +        mMinuteSpinner.findViewById(R.id.decrement).setContentDescription(text); +        // Hour +        text = mContext.getString(R.string.time_picker_increment_hour_button); +        mHourSpinner.findViewById(R.id.increment).setContentDescription(text); +        text = mContext.getString(R.string.time_picker_decrement_hour_button); +        mHourSpinner.findViewById(R.id.decrement).setContentDescription(text); +        // AM/PM +        text = mContext.getString(R.string.time_picker_increment_set_pm_button); +        mAmPmSpinner.findViewById(R.id.increment).setContentDescription(text); +        text = mContext.getString(R.string.time_picker_decrement_set_am_button); +        mAmPmSpinner.findViewById(R.id.decrement).setContentDescription(text); +    }  } diff --git a/core/java/com/android/internal/view/IInputMethodManager.aidl b/core/java/com/android/internal/view/IInputMethodManager.aidl index ce0299ca3d65..683aca542ba8 100644 --- a/core/java/com/android/internal/view/IInputMethodManager.aidl +++ b/core/java/com/android/internal/view/IInputMethodManager.aidl @@ -68,5 +68,5 @@ interface IInputMethodManager {      boolean setCurrentInputMethodSubtype(in InputMethodSubtype subtype);      boolean switchToLastInputMethod(in IBinder token);      boolean setInputMethodEnabled(String id, boolean enabled); -    boolean setAdditionalInputMethodSubtypes(String id, in InputMethodSubtype[] subtypes); +    oneway void setAdditionalInputMethodSubtypes(String id, in InputMethodSubtype[] subtypes);  } diff --git a/core/res/res/layout-sw600dp/status_bar_latest_event_ticker.xml b/core/res/res/layout-sw600dp/status_bar_latest_event_ticker.xml index 7631781d0f2a..269e086e1644 100644 --- a/core/res/res/layout-sw600dp/status_bar_latest_event_ticker.xml +++ b/core/res/res/layout-sw600dp/status_bar_latest_event_ticker.xml @@ -38,8 +38,8 @@          android:textAppearance="@style/TextAppearance.StatusBar.EventContent.Info"          android:layout_width="wrap_content"          android:layout_height="match_parent" -        android:layout_marginTop="-10dp" +        android:layout_marginBottom="6dip" +        android:gravity="bottom"          android:singleLine="true"          />  </LinearLayout> - diff --git a/core/res/res/layout-sw600dp/status_bar_latest_event_ticker_large_icon.xml b/core/res/res/layout-sw600dp/status_bar_latest_event_ticker_large_icon.xml index ff0f7d44e637..69eac92d8728 100644 --- a/core/res/res/layout-sw600dp/status_bar_latest_event_ticker_large_icon.xml +++ b/core/res/res/layout-sw600dp/status_bar_latest_event_ticker_large_icon.xml @@ -33,8 +33,9 @@          android:textAppearance="@style/TextAppearance.StatusBar.EventContent.Info"          android:layout_width="wrap_content"          android:layout_height="match_parent" +        android:layout_marginBottom="6dip" +        android:gravity="bottom"          android:singleLine="true" -        android:layout_marginTop="-10dp"          />      <ImageView android:id="@+id/icon"          android:layout_width="wrap_content" diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml index b50c063c3250..0bf5b0ac5dc9 100755 --- a/core/res/res/values/attrs.xml +++ b/core/res/res/values/attrs.xml @@ -2237,6 +2237,10 @@               InputMethodManager#switchToLastInputMethod will ignore auxiliary subtypes when it               chooses a target subtype. -->          <attr name="isAuxiliary" format="boolean" /> +        <!-- Set true when this subtype should be selected by default if no other subtypes are +             selected explicitly. Note that a subtype with this parameter being true will +             not be shown in the subtypes list. --> +        <attr name="overridesImplicitlyEnabledSubtype" format="boolean" />          <!-- The extra value of the subtype. This string can be any string and will be passed to               the IME when the framework calls the IME with the subtype.  -->          <attr name="imeSubtypeExtraValue" format="string" /> diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml index 6988f6bacf26..bc2b907c89cf 100644 --- a/core/res/res/values/public.xml +++ b/core/res/res/values/public.xml @@ -2010,4 +2010,5 @@    <public type="attr" name="targetDescriptions" />    <public type="attr" name="directionDescriptions" /> +  <public type="attr" name="overridesImplicitlyEnabledSubtype" />  </resources> diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml index 28253afd7243..5e010fef2264 100755 --- a/core/res/res/values/strings.xml +++ b/core/res/res/values/strings.xml @@ -3094,6 +3094,38 @@      <string name="number_picker_increment_button">Increment</string>      <!-- Description of the button to decrement the NumberPicker value. [CHAR LIMIT=NONE] -->      <string name="number_picker_decrement_button">Decrement</string> +    <!-- Description of the tap and hold action to get into scroll mode in NumberPicker. [CHAR LIMIT=NONE] --> +    <string name="number_picker_increment_scroll_mode"><xliff:g id="value" example="3">%s</xliff:g> tap and hold.</string> +    <!-- Description of the scrolling action in NumberPicker. [CHAR LIMIT=NONE] --> +    <string name="number_picker_increment_scroll_action">Slide up to increment and down to decrement.</string> + +    <!-- TimePicker - accessibility support --> +    <!-- Description of the button to increment the TimePicker's minute value. [CHAR LIMIT=NONE] --> +    <string name="time_picker_increment_minute_button">Increment minute</string> +    <!-- Description of the button to decrement the TimePicker's minute value. [CHAR LIMIT=NONE] --> +    <string name="time_picker_decrement_minute_button">Decrement minute</string> +    <!-- Description of the button to increment the TimePicker's hour value. [CHAR LIMIT=NONE] --> +    <string name="time_picker_increment_hour_button">Increment hour</string> +    <!-- Description of the button to decrement the TimePicker's hour value. [CHAR LIMIT=NONE] --> +    <string name="time_picker_decrement_hour_button">Decrement hour</string> +    <!-- Description of the button to increment the TimePicker's set PM value. [CHAR LIMIT=NONE] --> +    <string name="time_picker_increment_set_pm_button">Set PM</string> +    <!-- Description of the button to decrement the TimePicker's set AM value. [CHAR LIMIT=NONE] --> +    <string name="time_picker_decrement_set_am_button">Set AM</string> + +    <!-- DatePicker - accessibility support --> +    <!-- Description of the button to increment the DatePicker's month value. [CHAR LIMIT=NONE] --> +    <string name="date_picker_increment_month_button">Increment month</string> +    <!-- Description of the button to decrement the DatePicker's month value. [CHAR LIMIT=NONE] --> +    <string name="date_picker_decrement_month_button">Decrement month</string> +    <!-- Description of the button to increment the DatePicker's day value. [CHAR LIMIT=NONE] --> +    <string name="date_picker_increment_day_button">Increment day</string> +    <!-- Description of the button to decrement the DatePicker's day value. [CHAR LIMIT=NONE] --> +    <string name="date_picker_decrement_day_button">Decrement day</string> +    <!-- Description of the button to increment the DatePicker's year value. [CHAR LIMIT=NONE] --> +    <string name="date_picker_increment_year_button">Increment year</string> +    <!-- Description of the button to decrement the DatePicker's year value. [CHAR LIMIT=NONE] --> +    <string name="date_picker_decrement_year_button">Decrement year</string>      <!-- CheckBox - accessibility support -->      <!-- Description of the checked state of a CheckBox. [CHAR LIMIT=NONE] --> diff --git a/core/res/res/values/styles.xml b/core/res/res/values/styles.xml index fba1cd1b27fe..1a6a523538bd 100644 --- a/core/res/res/values/styles.xml +++ b/core/res/res/values/styles.xml @@ -1549,6 +1549,7 @@ please see styles_device_defaults.xml.      <style name="Widget.Holo.TextView.ListSeparator" parent="Widget.TextView.ListSeparator">          <item name="android:background">@android:drawable/list_section_divider_holo_dark</item> +        <item name="android:textAllCaps">true</item>      </style>      <style name="Widget.Holo.TextSelectHandle" parent="Widget.TextSelectHandle"> @@ -1992,6 +1993,7 @@ please see styles_device_defaults.xml.      <style name="Widget.Holo.Light.TextView.ListSeparator" parent="Widget.TextView.ListSeparator">          <item name="android:background">@android:drawable/list_section_divider_holo_light</item> +        <item name="android:textAllCaps">true</item>      </style>      <style name="Widget.Holo.Light.TextSelectHandle" parent="Widget.TextSelectHandle"> diff --git a/data/fonts/fallback_fonts.xml b/data/fonts/fallback_fonts.xml index 1bee47a6a867..e4685589f834 100644 --- a/data/fonts/fallback_fonts.xml +++ b/data/fonts/fallback_fonts.xml @@ -46,6 +46,16 @@      </family>      <family>          <fileset> +            <file>DroidSansArmenian.ttf</file> +        </fileset> +    </family> +    <family> +        <fileset> +            <file>DroidSansGeorgian.ttf</file> +        </fileset> +    </family> +    <family> +        <fileset>              <file>Lohit_Hindi.ttf</file>          </fileset>      </family> diff --git a/data/fonts/fonts.mk b/data/fonts/fonts.mk index 56bd2ce8b7ad..5bac8f00e479 100644 --- a/data/fonts/fonts.mk +++ b/data/fonts/fonts.mk @@ -31,6 +31,8 @@ PRODUCT_COPY_FILES := \      frameworks/base/data/fonts/DroidSerif-BoldItalic.ttf:system/fonts/DroidSerif-BoldItalic.ttf \      frameworks/base/data/fonts/DroidSansMono.ttf:system/fonts/DroidSansMono.ttf \      frameworks/base/data/fonts/Lohit_Hindi.ttf:system/fonts/Lohit_Hindi.ttf \ +    frameworks/base/data/fonts/DroidSansArmenian.ttf:system/fonts/DroidSansArmenian.ttf \ +    frameworks/base/data/fonts/DroidSansGeorgian.ttf:system/fonts/DroidSansGeorgian.ttf \      frameworks/base/data/fonts/Clockopia.ttf:system/fonts/Clockopia.ttf \      frameworks/base/data/fonts/AndroidClock.ttf:system/fonts/AndroidClock.ttf \      frameworks/base/data/fonts/AndroidClock_Highlight.ttf:system/fonts/AndroidClock_Highlight.ttf \ diff --git a/graphics/java/android/graphics/drawable/ColorDrawable.java b/graphics/java/android/graphics/drawable/ColorDrawable.java index 4418e02a89f5..88c91559dcbb 100644 --- a/graphics/java/android/graphics/drawable/ColorDrawable.java +++ b/graphics/java/android/graphics/drawable/ColorDrawable.java @@ -111,8 +111,11 @@ public class ColorDrawable extends Drawable {          alpha += alpha >> 7;   // make it 0..256          int baseAlpha = mState.mBaseColor >>> 24;          int useAlpha = baseAlpha * alpha >> 8; +        int oldUseColor = mState.mUseColor;          mState.mUseColor = (mState.mBaseColor << 8 >>> 8) | (useAlpha << 24); -        invalidateSelf(); +        if (oldUseColor != mState.mUseColor) { +            invalidateSelf(); +        }      }      /** diff --git a/include/media/IMediaPlayer.h b/include/media/IMediaPlayer.h index d552b2e23c5b..0e2cdf79ad19 100644 --- a/include/media/IMediaPlayer.h +++ b/include/media/IMediaPlayer.h @@ -20,11 +20,13 @@  #include <utils/RefBase.h>  #include <binder/IInterface.h>  #include <binder/Parcel.h> +#include <utils/KeyedVector.h>  namespace android {  class Parcel;  class Surface; +class IStreamSource;  class ISurfaceTexture;  class IMediaPlayer: public IInterface @@ -34,6 +36,10 @@ public:      virtual void            disconnect() = 0; +    virtual status_t        setDataSource(const char *url, +                                    const KeyedVector<String8, String8>* headers) = 0; +    virtual status_t        setDataSource(int fd, int64_t offset, int64_t length) = 0; +    virtual status_t        setDataSource(const sp<IStreamSource>& source) = 0;      virtual status_t        setVideoSurface(const sp<Surface>& surface) = 0;      virtual status_t        setVideoSurfaceTexture(                                      const sp<ISurfaceTexture>& surfaceTexture) = 0; diff --git a/include/media/IMediaPlayerService.h b/include/media/IMediaPlayerService.h index 795678881a01..93bbe13ea4c1 100644 --- a/include/media/IMediaPlayerService.h +++ b/include/media/IMediaPlayerService.h @@ -39,17 +39,9 @@ class IMediaPlayerService: public IInterface  public:      DECLARE_META_INTERFACE(MediaPlayerService); -    virtual sp<IMediaRecorder>  createMediaRecorder(pid_t pid) = 0; +    virtual sp<IMediaRecorder> createMediaRecorder(pid_t pid) = 0;      virtual sp<IMediaMetadataRetriever> createMetadataRetriever(pid_t pid) = 0; -    virtual sp<IMediaPlayer> create(pid_t pid, const sp<IMediaPlayerClient>& client, -            const char* url, const KeyedVector<String8, String8> *headers = NULL, -            int audioSessionId = 0) = 0; -    virtual sp<IMediaPlayer> create(pid_t pid, const sp<IMediaPlayerClient>& client, -            int fd, int64_t offset, int64_t length, int audioSessionId) = 0; - -    virtual sp<IMediaPlayer> create( -            pid_t pid, const sp<IMediaPlayerClient> &client, -            const sp<IStreamSource> &source, int audioSessionId) = 0; +    virtual sp<IMediaPlayer> create(pid_t pid, const sp<IMediaPlayerClient>& client, int audioSessionId = 0) = 0;      virtual sp<IMemory>         decode(const char* url, uint32_t *pSampleRate, int* pNumChannels, int* pFormat) = 0;      virtual sp<IMemory>         decode(int fd, int64_t offset, int64_t length, uint32_t *pSampleRate, int* pNumChannels, int* pFormat) = 0; diff --git a/include/media/mediaplayer.h b/include/media/mediaplayer.h index 1a676716afdd..e98d55cee502 100644 --- a/include/media/mediaplayer.h +++ b/include/media/mediaplayer.h @@ -21,6 +21,7 @@  #include <media/IMediaPlayerClient.h>  #include <media/IMediaPlayer.h>  #include <media/IMediaDeathNotifier.h> +#include <media/IStreamSource.h>  #include <utils/KeyedVector.h>  #include <utils/String8.h> @@ -168,6 +169,7 @@ public:                      const KeyedVector<String8, String8> *headers);              status_t        setDataSource(int fd, int64_t offset, int64_t length); +            status_t        setDataSource(const sp<IStreamSource> &source);              status_t        setVideoSurface(const sp<Surface>& surface);              status_t        setVideoSurfaceTexture(                                      const sp<ISurfaceTexture>& surfaceTexture); @@ -206,7 +208,7 @@ private:              status_t        seekTo_l(int msec);              status_t        prepareAsync_l();              status_t        getDuration_l(int *msec); -            status_t        setDataSource(const sp<IMediaPlayer>& player); +            status_t        attachNewPlayer(const sp<IMediaPlayer>& player);              void            disconnectNativeWindow();              status_t        reset_l(); diff --git a/libs/rs/rsScriptC.cpp b/libs/rs/rsScriptC.cpp index dccf71f046c8..2e7f2134fbaa 100644 --- a/libs/rs/rsScriptC.cpp +++ b/libs/rs/rsScriptC.cpp @@ -44,6 +44,7 @@ ScriptC::~ScriptC() {          BT = NULL;      }  #endif +    mRSC->mHal.funcs.script.invokeFreeChildren(mRSC, this);      mRSC->mHal.funcs.script.destroy(mRSC, this);  } diff --git a/libs/rs/scriptc/rs_quaternion.rsh b/libs/rs/scriptc/rs_quaternion.rsh index 36e6736c6c6f..23945ae691df 100644 --- a/libs/rs/scriptc/rs_quaternion.rsh +++ b/libs/rs/scriptc/rs_quaternion.rsh @@ -14,7 +14,7 @@   * limitations under the License.   */ -/** @file rs_matrix.rsh +/** @file rs_quaternion.rsh   *  \brief Quaternion routines   *   * diff --git a/media/java/android/media/MediaPlayer.java b/media/java/android/media/MediaPlayer.java index 1ee9a1fcc52b..e25f654f812f 100644 --- a/media/java/android/media/MediaPlayer.java +++ b/media/java/android/media/MediaPlayer.java @@ -459,6 +459,9 @@ import java.lang.ref.WeakReference;   * android.R.styleable#AndroidManifestUsesPermission <uses-permission>}   * element.   * + * <p>This class requires the {@link android.Manifest.permission#INTERNET} permission + * when used with network-based content. + *   * <a name="Callbacks"></a>   * <h3>Callbacks</h3>   * <p>Applications may want to register for informational and error @@ -828,6 +831,7 @@ public class MediaPlayer                  fd.close();              }          } +          Log.d(TAG, "Couldn't open file on client side, trying server side");          setDataSource(uri.toString(), headers);          return; @@ -839,7 +843,8 @@ public class MediaPlayer       * @param path the path of the file, or the http/rtsp URL of the stream you want to play       * @throws IllegalStateException if it is called in an invalid state       */ -    public native void setDataSource(String path) throws IOException, IllegalArgumentException, IllegalStateException; +    public native void setDataSource(String path) +            throws IOException, IllegalArgumentException, SecurityException, IllegalStateException;      /**       * Sets the data source (file-path or http/rtsp URL) to use. @@ -850,7 +855,7 @@ public class MediaPlayer       * @hide pending API council       */      public void setDataSource(String path, Map<String, String> headers) -            throws IOException, IllegalArgumentException, IllegalStateException +            throws IOException, IllegalArgumentException, SecurityException, IllegalStateException      {          String[] keys = null;          String[] values = null; @@ -871,7 +876,7 @@ public class MediaPlayer      private native void _setDataSource(          String path, String[] keys, String[] values) -        throws IOException, IllegalArgumentException, IllegalStateException; +        throws IOException, IllegalArgumentException, SecurityException, IllegalStateException;      /**       * Sets the data source (FileDescriptor) to use. It is the caller's responsibility diff --git a/media/jni/android_media_MediaPlayer.cpp b/media/jni/android_media_MediaPlayer.cpp index 354f2c94933a..5dfbe01396a1 100644 --- a/media/jni/android_media_MediaPlayer.cpp +++ b/media/jni/android_media_MediaPlayer.cpp @@ -155,6 +155,8 @@ static void process_media_player_call(JNIEnv *env, jobject thiz, status_t opStat      } else {  // Throw exception!          if ( opStatus == (status_t) INVALID_OPERATION ) {              jniThrowException(env, "java/lang/IllegalStateException", NULL); +        } else if ( opStatus == (status_t) PERMISSION_DENIED ) { +            jniThrowException(env, "java/lang/SecurityException", NULL);          } else if ( opStatus != (status_t) OK ) {              if (strlen(message) > 230) {                 // if the message is too long, don't bother displaying the status code diff --git a/media/libmedia/IMediaPlayer.cpp b/media/libmedia/IMediaPlayer.cpp index 52885d2e57b2..bd89ad824e99 100644 --- a/media/libmedia/IMediaPlayer.cpp +++ b/media/libmedia/IMediaPlayer.cpp @@ -21,14 +21,20 @@  #include <binder/Parcel.h>  #include <media/IMediaPlayer.h> +#include <media/IStreamSource.h> +  #include <surfaceflinger/ISurface.h>  #include <surfaceflinger/Surface.h>  #include <gui/ISurfaceTexture.h> +#include <utils/String8.h>  namespace android {  enum {      DISCONNECT = IBinder::FIRST_CALL_TRANSACTION, +    SET_DATA_SOURCE_URL, +    SET_DATA_SOURCE_FD, +    SET_DATA_SOURCE_STREAM,      SET_VIDEO_SURFACE,      PREPARE_ASYNC,      START, @@ -68,6 +74,43 @@ public:          remote()->transact(DISCONNECT, data, &reply);      } +    status_t setDataSource(const char* url, +            const KeyedVector<String8, String8>* headers) +    { +        Parcel data, reply; +        data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor()); +        data.writeCString(url); +        if (headers == NULL) { +            data.writeInt32(0); +        } else { +            // serialize the headers +            data.writeInt32(headers->size()); +            for (size_t i = 0; i < headers->size(); ++i) { +                data.writeString8(headers->keyAt(i)); +                data.writeString8(headers->valueAt(i)); +            } +        } +        remote()->transact(SET_DATA_SOURCE_URL, data, &reply); +        return reply.readInt32(); +    } + +    status_t setDataSource(int fd, int64_t offset, int64_t length) { +        Parcel data, reply; +        data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor()); +        data.writeFileDescriptor(fd); +        data.writeInt64(offset); +        data.writeInt64(length); +        remote()->transact(SET_DATA_SOURCE_FD, data, &reply); +        return reply.readInt32(); +    } + +    status_t setDataSource(const sp<IStreamSource> &source) { +        Parcel data, reply; +        data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor()); +        data.writeStrongBinder(source->asBinder()); +        return reply.readInt32(); +    } +      // pass the buffered Surface to the media player service      status_t setVideoSurface(const sp<Surface>& surface)      { @@ -273,6 +316,34 @@ status_t BnMediaPlayer::onTransact(              disconnect();              return NO_ERROR;          } break; +        case SET_DATA_SOURCE_URL: { +            CHECK_INTERFACE(IMediaPlayer, data, reply); +            const char* url = data.readCString(); +            KeyedVector<String8, String8> headers; +            int32_t numHeaders = data.readInt32(); +            for (int i = 0; i < numHeaders; ++i) { +                String8 key = data.readString8(); +                String8 value = data.readString8(); +                headers.add(key, value); +            } +            reply->writeInt32(setDataSource(url, numHeaders > 0 ? &headers : NULL)); +            return NO_ERROR; +        } break; +        case SET_DATA_SOURCE_FD: { +            CHECK_INTERFACE(IMediaPlayer, data, reply); +            int fd = data.readFileDescriptor(); +            int64_t offset = data.readInt64(); +            int64_t length = data.readInt64(); +            reply->writeInt32(setDataSource(fd, offset, length)); +            return NO_ERROR; +        } +        case SET_DATA_SOURCE_STREAM: { +            CHECK_INTERFACE(IMediaPlayer, data, reply); +            sp<IStreamSource> source = +                interface_cast<IStreamSource>(data.readStrongBinder()); +            reply->writeInt32(setDataSource(source)); +            return NO_ERROR; +        }          case SET_VIDEO_SURFACE: {              CHECK_INTERFACE(IMediaPlayer, data, reply);              sp<Surface> surface = Surface::readFromParcel(data); diff --git a/media/libmedia/IMediaPlayerService.cpp b/media/libmedia/IMediaPlayerService.cpp index 17a0362862e0..8e4dd04f811a 100644 --- a/media/libmedia/IMediaPlayerService.cpp +++ b/media/libmedia/IMediaPlayerService.cpp @@ -30,9 +30,7 @@  namespace android {  enum { -    CREATE_URL = IBinder::FIRST_CALL_TRANSACTION, -    CREATE_FD, -    CREATE_STREAM, +    CREATE = IBinder::FIRST_CALL_TRANSACTION,      DECODE_URL,      DECODE_FD,      CREATE_MEDIA_RECORDER, @@ -60,28 +58,14 @@ public:      }      virtual sp<IMediaPlayer> create( -            pid_t pid, const sp<IMediaPlayerClient>& client, -            const char* url, const KeyedVector<String8, String8> *headers, int audioSessionId) { +            pid_t pid, const sp<IMediaPlayerClient>& client, int audioSessionId) {          Parcel data, reply;          data.writeInterfaceToken(IMediaPlayerService::getInterfaceDescriptor());          data.writeInt32(pid);          data.writeStrongBinder(client->asBinder()); -        data.writeCString(url); - -        if (headers == NULL) { -            data.writeInt32(0); -        } else { -            // serialize the headers -            data.writeInt32(headers->size()); -            for (size_t i = 0; i < headers->size(); ++i) { -                data.writeString8(headers->keyAt(i)); -                data.writeString8(headers->valueAt(i)); -            } -        }          data.writeInt32(audioSessionId); -        remote()->transact(CREATE_URL, data, &reply); - +        remote()->transact(CREATE, data, &reply);          return interface_cast<IMediaPlayer>(reply.readStrongBinder());      } @@ -94,38 +78,6 @@ public:          return interface_cast<IMediaRecorder>(reply.readStrongBinder());      } -    virtual sp<IMediaPlayer> create(pid_t pid, const sp<IMediaPlayerClient>& client, int fd, -            int64_t offset, int64_t length, int audioSessionId) -    { -        Parcel data, reply; -        data.writeInterfaceToken(IMediaPlayerService::getInterfaceDescriptor()); -        data.writeInt32(pid); -        data.writeStrongBinder(client->asBinder()); -        data.writeFileDescriptor(fd); -        data.writeInt64(offset); -        data.writeInt64(length); -        data.writeInt32(audioSessionId); - -        remote()->transact(CREATE_FD, data, &reply); - -        return interface_cast<IMediaPlayer>(reply.readStrongBinder());; -    } - -    virtual sp<IMediaPlayer> create( -            pid_t pid, const sp<IMediaPlayerClient> &client, -            const sp<IStreamSource> &source, int audioSessionId) { -        Parcel data, reply; -        data.writeInterfaceToken(IMediaPlayerService::getInterfaceDescriptor()); -        data.writeInt32(static_cast<int32_t>(pid)); -        data.writeStrongBinder(client->asBinder()); -        data.writeStrongBinder(source->asBinder()); -        data.writeInt32(static_cast<int32_t>(audioSessionId)); - -        remote()->transact(CREATE_STREAM, data, &reply); - -        return interface_cast<IMediaPlayer>(reply.readStrongBinder());; -    } -      virtual sp<IMemory> decode(const char* url, uint32_t *pSampleRate, int* pNumChannels, int* pFormat)      {          Parcel data, reply; @@ -181,62 +133,16 @@ status_t BnMediaPlayerService::onTransact(      uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)  {      switch(code) { -        case CREATE_URL: { +        case CREATE: {              CHECK_INTERFACE(IMediaPlayerService, data, reply);              pid_t pid = data.readInt32();              sp<IMediaPlayerClient> client =                  interface_cast<IMediaPlayerClient>(data.readStrongBinder()); -            const char* url = data.readCString(); - -            KeyedVector<String8, String8> headers; -            int32_t numHeaders = data.readInt32(); -            for (int i = 0; i < numHeaders; ++i) { -                String8 key = data.readString8(); -                String8 value = data.readString8(); -                headers.add(key, value); -            } -            int audioSessionId = data.readInt32(); - -            sp<IMediaPlayer> player = create( -                    pid, client, url, numHeaders > 0 ? &headers : NULL, audioSessionId); - -            reply->writeStrongBinder(player->asBinder()); -            return NO_ERROR; -        } break; -        case CREATE_FD: { -            CHECK_INTERFACE(IMediaPlayerService, data, reply); -            pid_t pid = data.readInt32(); -            sp<IMediaPlayerClient> client = interface_cast<IMediaPlayerClient>(data.readStrongBinder()); -            int fd = dup(data.readFileDescriptor()); -            int64_t offset = data.readInt64(); -            int64_t length = data.readInt64();              int audioSessionId = data.readInt32(); - -            sp<IMediaPlayer> player = create(pid, client, fd, offset, length, audioSessionId); +            sp<IMediaPlayer> player = create(pid, client, audioSessionId);              reply->writeStrongBinder(player->asBinder());              return NO_ERROR;          } break; -        case CREATE_STREAM: -        { -            CHECK_INTERFACE(IMediaPlayerService, data, reply); - -            pid_t pid = static_cast<pid_t>(data.readInt32()); - -            sp<IMediaPlayerClient> client = -                interface_cast<IMediaPlayerClient>(data.readStrongBinder()); - -            sp<IStreamSource> source = -                interface_cast<IStreamSource>(data.readStrongBinder()); - -            int audioSessionId = static_cast<int>(data.readInt32()); - -            sp<IMediaPlayer> player = -                create(pid, client, source, audioSessionId); - -            reply->writeStrongBinder(player->asBinder()); -            return OK; -            break; -        }          case DECODE_URL: {              CHECK_INTERFACE(IMediaPlayerService, data, reply);              const char* url = data.readCString(); diff --git a/media/libmedia/mediaplayer.cpp b/media/libmedia/mediaplayer.cpp index 67a66a289f1c..0fc6a8a85138 100644 --- a/media/libmedia/mediaplayer.cpp +++ b/media/libmedia/mediaplayer.cpp @@ -108,7 +108,7 @@ status_t MediaPlayer::setListener(const sp<MediaPlayerListener>& listener)  } -status_t MediaPlayer::setDataSource(const sp<IMediaPlayer>& player) +status_t MediaPlayer::attachNewPlayer(const sp<IMediaPlayer>& player)  {      status_t err = UNKNOWN_ERROR;      sp<IMediaPlayer> p; @@ -117,7 +117,7 @@ status_t MediaPlayer::setDataSource(const sp<IMediaPlayer>& player)          if ( !( (mCurrentState & MEDIA_PLAYER_IDLE) ||                  (mCurrentState == MEDIA_PLAYER_STATE_ERROR ) ) ) { -            LOGE("setDataSource called in state %d", mCurrentState); +            LOGE("attachNewPlayer called in state %d", mCurrentState);              return INVALID_OPERATION;          } @@ -147,9 +147,11 @@ status_t MediaPlayer::setDataSource(      if (url != NULL) {          const sp<IMediaPlayerService>& service(getMediaPlayerService());          if (service != 0) { -            sp<IMediaPlayer> player( -                    service->create(getpid(), this, url, headers, mAudioSessionId)); -            err = setDataSource(player); +            sp<IMediaPlayer> player(service->create(getpid(), this, mAudioSessionId)); +            err = attachNewPlayer(player); +            if (err == NO_ERROR) { +                err = mPlayer->setDataSource(url, headers); +            }          }      }      return err; @@ -161,8 +163,26 @@ status_t MediaPlayer::setDataSource(int fd, int64_t offset, int64_t length)      status_t err = UNKNOWN_ERROR;      const sp<IMediaPlayerService>& service(getMediaPlayerService());      if (service != 0) { -        sp<IMediaPlayer> player(service->create(getpid(), this, fd, offset, length, mAudioSessionId)); -        err = setDataSource(player); +        sp<IMediaPlayer> player(service->create(getpid(), this, mAudioSessionId)); +        err = attachNewPlayer(player); +        if (err == NO_ERROR) { +            err = mPlayer->setDataSource(fd, offset, length); +        } +    } +    return err; +} + +status_t MediaPlayer::setDataSource(const sp<IStreamSource> &source) +{ +    LOGV("setDataSource"); +    status_t err = UNKNOWN_ERROR; +    const sp<IMediaPlayerService>& service(getMediaPlayerService()); +    if (service != 0) { +        sp<IMediaPlayer> player(service->create(getpid(), this, mAudioSessionId)); +        err = attachNewPlayer(player); +        if (err == NO_ERROR) { +            err = mPlayer->setDataSource(source); +        }      }      return err;  } diff --git a/media/libmediaplayerservice/MediaPlayerService.cpp b/media/libmediaplayerservice/MediaPlayerService.cpp index 2051b3ba49fe..0386d4b65987 100644 --- a/media/libmediaplayerservice/MediaPlayerService.cpp +++ b/media/libmediaplayerservice/MediaPlayerService.cpp @@ -176,6 +176,16 @@ bool findMetadata(const Metadata::Filter& filter, const int32_t val)  namespace android { +static bool checkPermission(const char* permissionString) { +#ifndef HAVE_ANDROID_OS +    return true; +#endif +    if (getpid() == IPCThreadState::self()->getCallingPid()) return true; +    bool ok = checkCallingPermission(String16(permissionString)); +    if (!ok) LOGE("Request requires %s", permissionString); +    return ok; +} +  // TODO: Temp hack until we can register players  typedef struct {      const char *extension; @@ -245,31 +255,8 @@ sp<IMediaMetadataRetriever> MediaPlayerService::createMetadataRetriever(pid_t pi      return retriever;  } -sp<IMediaPlayer> MediaPlayerService::create( -        pid_t pid, const sp<IMediaPlayerClient>& client, const char* url, -        const KeyedVector<String8, String8> *headers, int audioSessionId) -{ -    int32_t connId = android_atomic_inc(&mNextConnId); - -    sp<Client> c = new Client( -            this, pid, connId, client, audioSessionId, -            IPCThreadState::self()->getCallingUid()); - -    LOGV("Create new client(%d) from pid %d, uid %d, url=%s, connId=%d, audioSessionId=%d", -            connId, pid, IPCThreadState::self()->getCallingUid(), url, connId, audioSessionId); -    if (NO_ERROR != c->setDataSource(url, headers)) -    { -        c.clear(); -        return c; -    } -    wp<Client> w = c; -    Mutex::Autolock lock(mLock); -    mClients.add(w); -    return c; -} -  sp<IMediaPlayer> MediaPlayerService::create(pid_t pid, const sp<IMediaPlayerClient>& client, -        int fd, int64_t offset, int64_t length, int audioSessionId) +        int audioSessionId)  {      int32_t connId = android_atomic_inc(&mNextConnId); @@ -277,40 +264,14 @@ sp<IMediaPlayer> MediaPlayerService::create(pid_t pid, const sp<IMediaPlayerClie              this, pid, connId, client, audioSessionId,              IPCThreadState::self()->getCallingUid()); -    LOGV("Create new client(%d) from pid %d, uid %d, fd=%d, offset=%lld, " -         "length=%lld, audioSessionId=%d", connId, pid, -         IPCThreadState::self()->getCallingUid(), fd, offset, length, audioSessionId); -    if (NO_ERROR != c->setDataSource(fd, offset, length)) { -        c.clear(); -    } else { -        wp<Client> w = c; -        Mutex::Autolock lock(mLock); -        mClients.add(w); -    } -    ::close(fd); -    return c; -} - -sp<IMediaPlayer> MediaPlayerService::create( -        pid_t pid, const sp<IMediaPlayerClient> &client, -        const sp<IStreamSource> &source, int audioSessionId) { -    int32_t connId = android_atomic_inc(&mNextConnId); - -    sp<Client> c = new Client( -            this, pid, connId, client, audioSessionId, -            IPCThreadState::self()->getCallingUid()); - -    LOGV("Create new client(%d) from pid %d, audioSessionId=%d", -         connId, pid, audioSessionId); +    LOGV("Create new client(%d) from pid %d, uid %d, ", connId, pid, +         IPCThreadState::self()->getCallingUid()); -    if (OK != c->setDataSource(source)) { -        c.clear(); -    } else { -        wp<Client> w = c; +    wp<Client> w = c; +    {          Mutex::Autolock lock(mLock);          mClients.add(w);      } -      return c;  } @@ -701,6 +662,14 @@ status_t MediaPlayerService::Client::setDataSource(      if (url == NULL)          return UNKNOWN_ERROR; +    if ((strncmp(url, "http://", 7) == 0) || +        (strncmp(url, "https://", 8) == 0) || +        (strncmp(url, "rtsp://", 7) == 0)) { +        if (!checkPermission("android.permission.INTERNET")) { +            return PERMISSION_DENIED; +        } +    } +      if (strncmp(url, "content://", 10) == 0) {          // get a filedescriptor for the content Uri and          // pass it to the setDataSource(fd) method @@ -781,6 +750,7 @@ status_t MediaPlayerService::Client::setDataSource(int fd, int64_t offset, int64      // now set data source      mStatus = p->setDataSource(fd, offset, length);      if (mStatus == NO_ERROR) mPlayer = p; +      return mStatus;  } diff --git a/media/libmediaplayerservice/MediaPlayerService.h b/media/libmediaplayerservice/MediaPlayerService.h index e32b92a659ca..53e625a43855 100644 --- a/media/libmediaplayerservice/MediaPlayerService.h +++ b/media/libmediaplayerservice/MediaPlayerService.h @@ -188,16 +188,7 @@ public:      void    removeMediaRecorderClient(wp<MediaRecorderClient> client);      virtual sp<IMediaMetadataRetriever> createMetadataRetriever(pid_t pid); -    // House keeping for media player clients -    virtual sp<IMediaPlayer>    create( -            pid_t pid, const sp<IMediaPlayerClient>& client, const char* url, -            const KeyedVector<String8, String8> *headers, int audioSessionId); - -    virtual sp<IMediaPlayer>    create(pid_t pid, const sp<IMediaPlayerClient>& client, int fd, int64_t offset, int64_t length, int audioSessionId); - -    virtual sp<IMediaPlayer>    create( -            pid_t pid, const sp<IMediaPlayerClient> &client, -            const sp<IStreamSource> &source, int audioSessionId); +    virtual sp<IMediaPlayer>    create(pid_t pid, const sp<IMediaPlayerClient>& client, int audioSessionId);      virtual sp<IMemory>         decode(const char* url, uint32_t *pSampleRate, int* pNumChannels, int* pFormat);      virtual sp<IMemory>         decode(int fd, int64_t offset, int64_t length, uint32_t *pSampleRate, int* pNumChannels, int* pFormat); @@ -284,13 +275,13 @@ private:          sp<MediaPlayerBase>     createPlayer(player_type playerType); -                status_t        setDataSource( +        virtual status_t        setDataSource(                          const char *url,                          const KeyedVector<String8, String8> *headers); -                status_t        setDataSource(int fd, int64_t offset, int64_t length); +        virtual status_t        setDataSource(int fd, int64_t offset, int64_t length); -                status_t        setDataSource(const sp<IStreamSource> &source); +        virtual status_t        setDataSource(const sp<IStreamSource> &source);          static  void            notify(void* cookie, int msg,                                         int ext1, int ext2, const Parcel *obj); diff --git a/media/libstagefright/FileSource.cpp b/media/libstagefright/FileSource.cpp index f2f3500a71c8..0794f5770df4 100644 --- a/media/libstagefright/FileSource.cpp +++ b/media/libstagefright/FileSource.cpp @@ -110,6 +110,8 @@ ssize_t FileSource::readAt(off64_t offset, void *data, size_t size) {  }  status_t FileSource::getSize(off64_t *size) { +    Mutex::Autolock autoLock(mLock); +      if (mFd < 0) {          return NO_INIT;      } diff --git a/opengl/libs/GLES2_dbg/src/dbgcontext.cpp b/opengl/libs/GLES2_dbg/src/dbgcontext.cpp index ff9be3cef32b..9e77665eba52 100644 --- a/opengl/libs/GLES2_dbg/src/dbgcontext.cpp +++ b/opengl/libs/GLES2_dbg/src/dbgcontext.cpp @@ -88,7 +88,7 @@ DbgContext* CreateDbgContext(const unsigned version, const gl_hooks_t * const ho      msg.set_arg1(MAX_COMBINED_TEXTURE_IMAGE_UNITS);      Send(msg, cmd); -    *(DbgContext **)pthread_getspecific(dbgEGLThreadLocalStorageKey) = dbg; +    pthread_setspecific(dbgEGLThreadLocalStorageKey, dbg);      return dbg;  } diff --git a/packages/SystemUI/res/drawable-hdpi/recents_bg_protect_tile.png b/packages/SystemUI/res/drawable-hdpi/recents_bg_protect_tile.pngBinary files differ deleted file mode 100644 index 87c7be69a357..000000000000 --- a/packages/SystemUI/res/drawable-hdpi/recents_bg_protect_tile.png +++ /dev/null diff --git a/packages/SystemUI/res/drawable-hdpi/recents_blue_glow.9.png b/packages/SystemUI/res/drawable-hdpi/recents_blue_glow.9.pngBinary files differ index 4f4ae788e3f1..436283618f54 100644 --- a/packages/SystemUI/res/drawable-hdpi/recents_blue_glow.9.png +++ b/packages/SystemUI/res/drawable-hdpi/recents_blue_glow.9.png diff --git a/packages/SystemUI/res/drawable-hdpi/recents_callout_line.9.png b/packages/SystemUI/res/drawable-hdpi/recents_callout_line.9.pngBinary files differ new file mode 100644 index 000000000000..335d5a8171d5 --- /dev/null +++ b/packages/SystemUI/res/drawable-hdpi/recents_callout_line.9.png diff --git a/packages/SystemUI/res/drawable-hdpi/recents_callout_line.png b/packages/SystemUI/res/drawable-hdpi/recents_callout_line.pngBinary files differ deleted file mode 100644 index 5f4c0357e674..000000000000 --- a/packages/SystemUI/res/drawable-hdpi/recents_callout_line.png +++ /dev/null diff --git a/packages/SystemUI/res/drawable-hdpi/recents_thumbnail_bg.9.png b/packages/SystemUI/res/drawable-hdpi/recents_thumbnail_bg.9.pngBinary files differ new file mode 100644 index 000000000000..1ad16f76035c --- /dev/null +++ b/packages/SystemUI/res/drawable-hdpi/recents_thumbnail_bg.9.png diff --git a/packages/SystemUI/res/drawable-hdpi/recents_thumbnail_bg.png b/packages/SystemUI/res/drawable-hdpi/recents_thumbnail_bg.pngBinary files differ deleted file mode 100644 index 23aabcefcef1..000000000000 --- a/packages/SystemUI/res/drawable-hdpi/recents_thumbnail_bg.png +++ /dev/null diff --git a/packages/SystemUI/res/drawable-hdpi/recents_thumbnail_bg_press.9.png b/packages/SystemUI/res/drawable-hdpi/recents_thumbnail_bg_press.9.pngBinary files differ new file mode 100644 index 000000000000..6e806eefd627 --- /dev/null +++ b/packages/SystemUI/res/drawable-hdpi/recents_thumbnail_bg_press.9.png diff --git a/packages/SystemUI/res/drawable-hdpi/recents_thumbnail_bg_press.png b/packages/SystemUI/res/drawable-hdpi/recents_thumbnail_bg_press.pngBinary files differ deleted file mode 100644 index 0b0765b5cc21..000000000000 --- a/packages/SystemUI/res/drawable-hdpi/recents_thumbnail_bg_press.png +++ /dev/null diff --git a/packages/SystemUI/res/drawable-large-hdpi/app_icon.png b/packages/SystemUI/res/drawable-large-hdpi/app_icon.pngBinary files differ deleted file mode 100644 index 52354bde6c1e..000000000000 --- a/packages/SystemUI/res/drawable-large-hdpi/app_icon.png +++ /dev/null diff --git a/packages/SystemUI/res/drawable-large-hdpi/recents_bg_protect_tile.png b/packages/SystemUI/res/drawable-large-hdpi/recents_bg_protect_tile.pngBinary files differ deleted file mode 100644 index ce01276a3c5c..000000000000 --- a/packages/SystemUI/res/drawable-large-hdpi/recents_bg_protect_tile.png +++ /dev/null diff --git a/packages/SystemUI/res/drawable-large-hdpi/recents_blue_glow.9.png b/packages/SystemUI/res/drawable-large-hdpi/recents_blue_glow.9.pngBinary files differ deleted file mode 100644 index 1848fcdbc838..000000000000 --- a/packages/SystemUI/res/drawable-large-hdpi/recents_blue_glow.9.png +++ /dev/null diff --git a/packages/SystemUI/res/drawable-large-hdpi/recents_callout_line.png b/packages/SystemUI/res/drawable-large-hdpi/recents_callout_line.pngBinary files differ deleted file mode 100644 index 61a3f87e44dd..000000000000 --- a/packages/SystemUI/res/drawable-large-hdpi/recents_callout_line.png +++ /dev/null diff --git a/packages/SystemUI/res/drawable-large-hdpi/recents_thumbnail_bg.png b/packages/SystemUI/res/drawable-large-hdpi/recents_thumbnail_bg.pngBinary files differ deleted file mode 100644 index b6aca49929a5..000000000000 --- a/packages/SystemUI/res/drawable-large-hdpi/recents_thumbnail_bg.png +++ /dev/null diff --git a/packages/SystemUI/res/drawable-large-hdpi/recents_thumbnail_bg_press.png b/packages/SystemUI/res/drawable-large-hdpi/recents_thumbnail_bg_press.pngBinary files differ deleted file mode 100644 index 226aaac24e55..000000000000 --- a/packages/SystemUI/res/drawable-large-hdpi/recents_thumbnail_bg_press.png +++ /dev/null diff --git a/packages/SystemUI/res/drawable-large-mdpi/app_icon.png b/packages/SystemUI/res/drawable-large-mdpi/app_icon.pngBinary files differ deleted file mode 100644 index 001811f2bc91..000000000000 --- a/packages/SystemUI/res/drawable-large-mdpi/app_icon.png +++ /dev/null diff --git a/packages/SystemUI/res/drawable-large-mdpi/recents_bg_protect_tile.png b/packages/SystemUI/res/drawable-large-mdpi/recents_bg_protect_tile.pngBinary files differ deleted file mode 100644 index 3d0fbf216fb2..000000000000 --- a/packages/SystemUI/res/drawable-large-mdpi/recents_bg_protect_tile.png +++ /dev/null diff --git a/packages/SystemUI/res/drawable-large-mdpi/recents_blue_glow.9.png b/packages/SystemUI/res/drawable-large-mdpi/recents_blue_glow.9.pngBinary files differ deleted file mode 100644 index 436283618f54..000000000000 --- a/packages/SystemUI/res/drawable-large-mdpi/recents_blue_glow.9.png +++ /dev/null diff --git a/packages/SystemUI/res/drawable-large-mdpi/recents_callout_line.png b/packages/SystemUI/res/drawable-large-mdpi/recents_callout_line.pngBinary files differ deleted file mode 100644 index f4ccd7ee29a6..000000000000 --- a/packages/SystemUI/res/drawable-large-mdpi/recents_callout_line.png +++ /dev/null diff --git a/packages/SystemUI/res/drawable-large-mdpi/recents_thumbnail_bg.png b/packages/SystemUI/res/drawable-large-mdpi/recents_thumbnail_bg.pngBinary files differ deleted file mode 100644 index 6392fa16742d..000000000000 --- a/packages/SystemUI/res/drawable-large-mdpi/recents_thumbnail_bg.png +++ /dev/null diff --git a/packages/SystemUI/res/drawable-large-mdpi/recents_thumbnail_bg_press.png b/packages/SystemUI/res/drawable-large-mdpi/recents_thumbnail_bg_press.pngBinary files differ deleted file mode 100644 index f6ee5967dfd3..000000000000 --- a/packages/SystemUI/res/drawable-large-mdpi/recents_thumbnail_bg_press.png +++ /dev/null diff --git a/packages/SystemUI/res/drawable-mdpi/recents_bg_protect_tile.png b/packages/SystemUI/res/drawable-mdpi/recents_bg_protect_tile.pngBinary files differ deleted file mode 100644 index 87c7be69a357..000000000000 --- a/packages/SystemUI/res/drawable-mdpi/recents_bg_protect_tile.png +++ /dev/null diff --git a/packages/SystemUI/res/drawable-mdpi/recents_blue_glow.9.png b/packages/SystemUI/res/drawable-mdpi/recents_blue_glow.9.pngBinary files differ index 4f4ae788e3f1..436283618f54 100644 --- a/packages/SystemUI/res/drawable-mdpi/recents_blue_glow.9.png +++ b/packages/SystemUI/res/drawable-mdpi/recents_blue_glow.9.png diff --git a/packages/SystemUI/res/drawable-mdpi/recents_callout_line.9.png b/packages/SystemUI/res/drawable-mdpi/recents_callout_line.9.pngBinary files differ new file mode 100644 index 000000000000..724a5cd73b6a --- /dev/null +++ b/packages/SystemUI/res/drawable-mdpi/recents_callout_line.9.png diff --git a/packages/SystemUI/res/drawable-mdpi/recents_callout_line.png b/packages/SystemUI/res/drawable-mdpi/recents_callout_line.pngBinary files differ deleted file mode 100644 index 5f4c0357e674..000000000000 --- a/packages/SystemUI/res/drawable-mdpi/recents_callout_line.png +++ /dev/null diff --git a/packages/SystemUI/res/drawable-mdpi/recents_thumbnail_bg.9.png b/packages/SystemUI/res/drawable-mdpi/recents_thumbnail_bg.9.pngBinary files differ new file mode 100644 index 000000000000..82ba0913926d --- /dev/null +++ b/packages/SystemUI/res/drawable-mdpi/recents_thumbnail_bg.9.png diff --git a/packages/SystemUI/res/drawable-mdpi/recents_thumbnail_bg.png b/packages/SystemUI/res/drawable-mdpi/recents_thumbnail_bg.pngBinary files differ deleted file mode 100644 index 23aabcefcef1..000000000000 --- a/packages/SystemUI/res/drawable-mdpi/recents_thumbnail_bg.png +++ /dev/null diff --git a/packages/SystemUI/res/drawable-mdpi/recents_thumbnail_bg_press.9.png b/packages/SystemUI/res/drawable-mdpi/recents_thumbnail_bg_press.9.pngBinary files differ new file mode 100644 index 000000000000..7376085be66d --- /dev/null +++ b/packages/SystemUI/res/drawable-mdpi/recents_thumbnail_bg_press.9.png diff --git a/packages/SystemUI/res/drawable-mdpi/recents_thumbnail_bg_press.png b/packages/SystemUI/res/drawable-mdpi/recents_thumbnail_bg_press.pngBinary files differ deleted file mode 100644 index 0b0765b5cc21..000000000000 --- a/packages/SystemUI/res/drawable-mdpi/recents_thumbnail_bg_press.png +++ /dev/null diff --git a/packages/SystemUI/res/drawable-sw600dp-hdpi/recents_blue_glow.9.png b/packages/SystemUI/res/drawable-sw600dp-hdpi/recents_blue_glow.9.pngBinary files differ new file mode 100644 index 000000000000..4ac131a62231 --- /dev/null +++ b/packages/SystemUI/res/drawable-sw600dp-hdpi/recents_blue_glow.9.png diff --git a/packages/SystemUI/res/drawable-sw600dp-mdpi/recents_blue_glow.9.png b/packages/SystemUI/res/drawable-sw600dp-mdpi/recents_blue_glow.9.pngBinary files differ index 4f4ae788e3f1..436283618f54 100644 --- a/packages/SystemUI/res/drawable-sw600dp-mdpi/recents_blue_glow.9.png +++ b/packages/SystemUI/res/drawable-sw600dp-mdpi/recents_blue_glow.9.png diff --git a/packages/SystemUI/res/drawable-sw600dp-mdpi/recents_callout_line.png b/packages/SystemUI/res/drawable-sw600dp-mdpi/recents_callout_line.pngBinary files differ deleted file mode 100644 index 5f4c0357e674..000000000000 --- a/packages/SystemUI/res/drawable-sw600dp-mdpi/recents_callout_line.png +++ /dev/null diff --git a/packages/SystemUI/res/drawable-sw600dp-mdpi/recents_thumbnail_bg.png b/packages/SystemUI/res/drawable-sw600dp-mdpi/recents_thumbnail_bg.pngBinary files differ deleted file mode 100644 index 87a67c9cf474..000000000000 --- a/packages/SystemUI/res/drawable-sw600dp-mdpi/recents_thumbnail_bg.png +++ /dev/null diff --git a/packages/SystemUI/res/drawable-sw600dp-mdpi/recents_thumbnail_bg_press.png b/packages/SystemUI/res/drawable-sw600dp-mdpi/recents_thumbnail_bg_press.pngBinary files differ deleted file mode 100644 index a1c39e6ec046..000000000000 --- a/packages/SystemUI/res/drawable-sw600dp-mdpi/recents_thumbnail_bg_press.png +++ /dev/null diff --git a/packages/SystemUI/res/drawable-sw600dp-xhdpi/recents_bg_protect_tile.png b/packages/SystemUI/res/drawable-sw600dp-xhdpi/recents_bg_protect_tile.pngBinary files differ new file mode 100644 index 000000000000..59908ad70736 --- /dev/null +++ b/packages/SystemUI/res/drawable-sw600dp-xhdpi/recents_bg_protect_tile.png diff --git a/packages/SystemUI/res/drawable-sw600dp-xhdpi/recents_blue_glow.9.png b/packages/SystemUI/res/drawable-sw600dp-xhdpi/recents_blue_glow.9.pngBinary files differ new file mode 100644 index 000000000000..393850286817 --- /dev/null +++ b/packages/SystemUI/res/drawable-sw600dp-xhdpi/recents_blue_glow.9.png diff --git a/packages/SystemUI/res/drawable-xhdpi/recents_blue_glow.9.png b/packages/SystemUI/res/drawable-xhdpi/recents_blue_glow.9.pngBinary files differ new file mode 100644 index 000000000000..e1e08c6fbd2b --- /dev/null +++ b/packages/SystemUI/res/drawable-xhdpi/recents_blue_glow.9.png diff --git a/packages/SystemUI/res/drawable-xhdpi/recents_callout_line.9.png b/packages/SystemUI/res/drawable-xhdpi/recents_callout_line.9.pngBinary files differ new file mode 100644 index 000000000000..1bd018ace35b --- /dev/null +++ b/packages/SystemUI/res/drawable-xhdpi/recents_callout_line.9.png diff --git a/packages/SystemUI/res/drawable-xhdpi/recents_thumbnail_bg.9.png b/packages/SystemUI/res/drawable-xhdpi/recents_thumbnail_bg.9.pngBinary files differ new file mode 100644 index 000000000000..0352aca3af0c --- /dev/null +++ b/packages/SystemUI/res/drawable-xhdpi/recents_thumbnail_bg.9.png diff --git a/packages/SystemUI/res/drawable-xhdpi/recents_thumbnail_bg_press.9.png b/packages/SystemUI/res/drawable-xhdpi/recents_thumbnail_bg_press.9.pngBinary files differ new file mode 100644 index 000000000000..507ee22b45d7 --- /dev/null +++ b/packages/SystemUI/res/drawable-xhdpi/recents_thumbnail_bg_press.9.png diff --git a/packages/SystemUI/res/drawable-xlarge-hdpi/app_icon.png b/packages/SystemUI/res/drawable-xlarge-hdpi/app_icon.pngBinary files differ deleted file mode 100644 index 52354bde6c1e..000000000000 --- a/packages/SystemUI/res/drawable-xlarge-hdpi/app_icon.png +++ /dev/null diff --git a/packages/SystemUI/res/drawable-xlarge-hdpi/recents_bg_protect_tile.png b/packages/SystemUI/res/drawable-xlarge-hdpi/recents_bg_protect_tile.pngBinary files differ deleted file mode 100644 index ce01276a3c5c..000000000000 --- a/packages/SystemUI/res/drawable-xlarge-hdpi/recents_bg_protect_tile.png +++ /dev/null diff --git a/packages/SystemUI/res/drawable-xlarge-hdpi/recents_blue_glow.9.png b/packages/SystemUI/res/drawable-xlarge-hdpi/recents_blue_glow.9.pngBinary files differ deleted file mode 100644 index 1848fcdbc838..000000000000 --- a/packages/SystemUI/res/drawable-xlarge-hdpi/recents_blue_glow.9.png +++ /dev/null diff --git a/packages/SystemUI/res/drawable-xlarge-hdpi/recents_callout_line.png b/packages/SystemUI/res/drawable-xlarge-hdpi/recents_callout_line.pngBinary files differ deleted file mode 100644 index 846bc492cacd..000000000000 --- a/packages/SystemUI/res/drawable-xlarge-hdpi/recents_callout_line.png +++ /dev/null diff --git a/packages/SystemUI/res/drawable-xlarge-hdpi/recents_thumbnail_bg.png b/packages/SystemUI/res/drawable-xlarge-hdpi/recents_thumbnail_bg.pngBinary files differ deleted file mode 100644 index a983e12d798c..000000000000 --- a/packages/SystemUI/res/drawable-xlarge-hdpi/recents_thumbnail_bg.png +++ /dev/null diff --git a/packages/SystemUI/res/drawable-xlarge-hdpi/recents_thumbnail_bg_press.png b/packages/SystemUI/res/drawable-xlarge-hdpi/recents_thumbnail_bg_press.pngBinary files differ deleted file mode 100644 index 7c6e44e70b91..000000000000 --- a/packages/SystemUI/res/drawable-xlarge-hdpi/recents_thumbnail_bg_press.png +++ /dev/null diff --git a/packages/SystemUI/res/drawable-xlarge-mdpi/app_icon.png b/packages/SystemUI/res/drawable-xlarge-mdpi/app_icon.pngBinary files differ deleted file mode 100644 index 001811f2bc91..000000000000 --- a/packages/SystemUI/res/drawable-xlarge-mdpi/app_icon.png +++ /dev/null diff --git a/packages/SystemUI/res/drawable-xlarge-mdpi/recents_bg_protect_tile.png b/packages/SystemUI/res/drawable-xlarge-mdpi/recents_bg_protect_tile.pngBinary files differ deleted file mode 100644 index 3d0fbf216fb2..000000000000 --- a/packages/SystemUI/res/drawable-xlarge-mdpi/recents_bg_protect_tile.png +++ /dev/null diff --git a/packages/SystemUI/res/drawable-xlarge-mdpi/recents_blue_glow.9.png b/packages/SystemUI/res/drawable-xlarge-mdpi/recents_blue_glow.9.pngBinary files differ deleted file mode 100644 index 436283618f54..000000000000 --- a/packages/SystemUI/res/drawable-xlarge-mdpi/recents_blue_glow.9.png +++ /dev/null diff --git a/packages/SystemUI/res/drawable-xlarge-mdpi/recents_callout_line.png b/packages/SystemUI/res/drawable-xlarge-mdpi/recents_callout_line.pngBinary files differ deleted file mode 100644 index f4ccd7ee29a6..000000000000 --- a/packages/SystemUI/res/drawable-xlarge-mdpi/recents_callout_line.png +++ /dev/null diff --git a/packages/SystemUI/res/drawable-xlarge-mdpi/recents_thumbnail_bg.png b/packages/SystemUI/res/drawable-xlarge-mdpi/recents_thumbnail_bg.pngBinary files differ deleted file mode 100644 index 6392fa16742d..000000000000 --- a/packages/SystemUI/res/drawable-xlarge-mdpi/recents_thumbnail_bg.png +++ /dev/null diff --git a/packages/SystemUI/res/drawable-xlarge-mdpi/recents_thumbnail_bg_press.png b/packages/SystemUI/res/drawable-xlarge-mdpi/recents_thumbnail_bg_press.pngBinary files differ deleted file mode 100644 index f6ee5967dfd3..000000000000 --- a/packages/SystemUI/res/drawable-xlarge-mdpi/recents_thumbnail_bg_press.png +++ /dev/null diff --git a/packages/SystemUI/res/drawable/recents_thumbnail_overlay.xml b/packages/SystemUI/res/drawable/recents_thumbnail_overlay.xml index 200bac40b947..6d0509511ecc 100644 --- a/packages/SystemUI/res/drawable/recents_thumbnail_overlay.xml +++ b/packages/SystemUI/res/drawable/recents_thumbnail_overlay.xml @@ -15,5 +15,6 @@  -->  <selector xmlns:android="http://schemas.android.com/apk/res/android">      <item android:drawable="@drawable/recents_thumbnail_bg_press" android:state_pressed="true" /> +    <item android:drawable="@drawable/recents_thumbnail_bg" android:state_activated="true" />      <item android:drawable="@*android:color/transparent"/>  </selector> diff --git a/packages/SystemUI/res/layout-land/status_bar_recent_item.xml b/packages/SystemUI/res/layout-land/status_bar_recent_item.xml index 42db77e12311..e99888c96614 100644 --- a/packages/SystemUI/res/layout-land/status_bar_recent_item.xml +++ b/packages/SystemUI/res/layout-land/status_bar_recent_item.xml @@ -38,8 +38,7 @@              android:layout_marginLeft="@dimen/status_bar_recents_thumbnail_left_margin"              android:scaleType="center"              android:clickable="true" -            android:background="@drawable/recents_thumbnail_bg" -            android:foreground="@drawable/recents_thumbnail_overlay"> +            android:background="@drawable/recents_thumbnail_overlay">              <ImageView android:id="@+id/app_thumbnail_image"                  android:layout_width="match_parent"                  android:layout_height="match_parent" @@ -54,8 +53,8 @@              android:layout_alignTop="@id/app_thumbnail"              android:layout_marginTop="@dimen/status_bar_recents_app_icon_top_margin"              android:layout_marginLeft="@dimen/status_bar_recents_app_icon_left_margin" -            android:maxWidth="@dimen/status_bar_recents_thumbnail_max_width" -            android:maxHeight="@dimen/status_bar_recents_thumbnail_max_height" +            android:maxWidth="@dimen/status_bar_recents_app_icon_max_width" +            android:maxHeight="@dimen/status_bar_recents_app_icon_max_height"              android:adjustViewBounds="true"              android:visibility="invisible"          /> @@ -70,7 +69,6 @@              android:layout_alignLeft="@id/app_thumbnail"              android:layout_below="@id/app_thumbnail"              android:layout_marginTop="@dimen/status_bar_recents_text_description_padding" -            android:layout_marginLeft="@dimen/recents_thumbnail_bg_padding_left"              android:singleLine="true"              android:ellipsize="marquee"              android:visibility="invisible" @@ -86,7 +84,6 @@              android:layout_alignLeft="@id/app_thumbnail"              android:layout_below="@id/app_label"              android:layout_marginTop="@dimen/status_bar_recents_text_description_padding" -            android:layout_marginLeft="@dimen/recents_thumbnail_bg_padding_left"              android:singleLine="true"              android:ellipsize="marquee"          /> diff --git a/packages/SystemUI/res/layout-port/status_bar_recent_item.xml b/packages/SystemUI/res/layout-port/status_bar_recent_item.xml index f6b72d43906d..73ca335e134e 100644 --- a/packages/SystemUI/res/layout-port/status_bar_recent_item.xml +++ b/packages/SystemUI/res/layout-port/status_bar_recent_item.xml @@ -36,8 +36,7 @@              android:clickable="true"              android:layout_marginLeft="@dimen/status_bar_recents_thumbnail_left_margin"              android:scaleType="center" -            android:background="@drawable/recents_thumbnail_bg" -            android:foreground="@drawable/recents_thumbnail_overlay"> +            android:background="@drawable/recents_thumbnail_overlay">              <ImageView android:id="@+id/app_thumbnail_image"                  android:layout_width="match_parent"                  android:layout_height="match_parent" @@ -52,8 +51,8 @@              android:layout_alignTop="@id/app_thumbnail"              android:layout_marginLeft="@dimen/status_bar_recents_app_icon_left_margin"              android:layout_marginTop="@dimen/status_bar_recents_app_icon_top_margin" -            android:maxWidth="@dimen/status_bar_recents_thumbnail_max_width" -            android:maxHeight="@dimen/status_bar_recents_thumbnail_max_height" +            android:maxWidth="@dimen/status_bar_recents_app_icon_max_width" +            android:maxHeight="@dimen/status_bar_recents_app_icon_max_height"              android:adjustViewBounds="true"          /> diff --git a/packages/SystemUI/res/layout-sw600dp/status_bar_recent_item.xml b/packages/SystemUI/res/layout-sw600dp/status_bar_recent_item.xml index 8dab2e6ba12f..cab90fd4b05f 100644 --- a/packages/SystemUI/res/layout-sw600dp/status_bar_recent_item.xml +++ b/packages/SystemUI/res/layout-sw600dp/status_bar_recent_item.xml @@ -29,11 +29,10 @@          android:layout_height="wrap_content"          android:layout_alignParentLeft="true"          android:layout_alignParentTop="true" +        android:clickable="true"          android:layout_marginLeft="@dimen/status_bar_recents_thumbnail_left_margin"          android:scaleType="center" -        android:clickable="true" -        android:background="@drawable/recents_thumbnail_bg" -        android:foreground="@drawable/recents_thumbnail_overlay"> +        android:background="@drawable/recents_thumbnail_overlay">          <ImageView android:id="@+id/app_thumbnail_image"              android:layout_width="match_parent"              android:layout_height="match_parent" @@ -48,8 +47,8 @@          android:layout_alignTop="@id/app_thumbnail"          android:layout_marginLeft="@dimen/status_bar_recents_app_icon_left_margin"          android:layout_marginTop="@dimen/status_bar_recents_app_icon_top_margin" -        android:maxWidth="@dimen/status_bar_recents_thumbnail_max_width" -        android:maxHeight="@dimen/status_bar_recents_thumbnail_max_height" +        android:maxWidth="@dimen/status_bar_recents_app_icon_max_width" +        android:maxHeight="@dimen/status_bar_recents_app_icon_max_height"          android:adjustViewBounds="true"      /> diff --git a/packages/SystemUI/res/layout-sw600dp/status_bar_recent_panel.xml b/packages/SystemUI/res/layout-sw600dp/status_bar_recent_panel.xml index 2c9a15202b31..4ef602ee3178 100644 --- a/packages/SystemUI/res/layout-sw600dp/status_bar_recent_panel.xml +++ b/packages/SystemUI/res/layout-sw600dp/status_bar_recent_panel.xml @@ -47,7 +47,7 @@              android:clipChildren="false"              >              <com.android.systemui.recent.RecentsVerticalScrollView android:id="@+id/recents_container" -                android:layout_width="@dimen/status_bar_recents_width" +                android:layout_width="wrap_content"                  android:layout_height="wrap_content"                  android:layout_marginRight="@dimen/status_bar_recents_right_glow_margin"                  android:divider="@null" diff --git a/packages/SystemUI/res/values-hdpi/dimens.xml b/packages/SystemUI/res/values-hdpi/dimens.xml index 287e0d162dd8..6b6fd4d63736 100644 --- a/packages/SystemUI/res/values-hdpi/dimens.xml +++ b/packages/SystemUI/res/values-hdpi/dimens.xml @@ -16,12 +16,6 @@  */  -->  <resources> -    <!-- Offsets for rendering thumbnails over drawable recents_thumbnail_bg --> -    <dimen name="recents_thumbnail_bg_padding_left">6px</dimen> -    <dimen name="recents_thumbnail_bg_padding_top">7px</dimen> -    <dimen name="recents_thumbnail_bg_padding_right">6px</dimen> -    <dimen name="recents_thumbnail_bg_padding_bottom">6px</dimen> -      <!-- thickness (height) of each notification row, including any separators or padding -->      <!-- Note: this is 64dip + 1px divider = 97px. -->      <dimen name="notification_height">97px</dimen> diff --git a/packages/SystemUI/res/values-land/dimens.xml b/packages/SystemUI/res/values-land/dimens.xml index 656c7c1d7451..ca74b8b42bbb 100644 --- a/packages/SystemUI/res/values-land/dimens.xml +++ b/packages/SystemUI/res/values-land/dimens.xml @@ -24,8 +24,6 @@      <dimen name="status_bar_recents_thumbnail_left_margin">8dp</dimen>      <!-- How far the thumbnail for a recent app appears from top edge -->      <dimen name="status_bar_recents_thumbnail_top_margin">12dp</dimen> -    <!-- Width of scrollable area in recents --> -    <dimen name="status_bar_recents_width">128dp</dimen>      <!-- Padding for text descriptions -->      <dimen name="status_bar_recents_text_description_padding">8dp</dimen>      <!-- Width of application label text --> diff --git a/packages/SystemUI/res/values-mdpi/dimens.xml b/packages/SystemUI/res/values-mdpi/dimens.xml deleted file mode 100644 index 741b75a55a6a..000000000000 --- a/packages/SystemUI/res/values-mdpi/dimens.xml +++ /dev/null @@ -1,24 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- - * Copyright (c) 2011, 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. -*/ ---> -<resources> -    <!-- Offsets for rendering thumbnails over drawable recents_thumbnail_bg --> -    <dimen name="recents_thumbnail_bg_padding_left">6px</dimen> -    <dimen name="recents_thumbnail_bg_padding_top">7px</dimen> -    <dimen name="recents_thumbnail_bg_padding_right">6px</dimen> -    <dimen name="recents_thumbnail_bg_padding_bottom">6px</dimen> -</resources> diff --git a/packages/SystemUI/res/values-port/dimens.xml b/packages/SystemUI/res/values-port/dimens.xml index 03b17e99cbf0..b89a610020e6 100644 --- a/packages/SystemUI/res/values-port/dimens.xml +++ b/packages/SystemUI/res/values-port/dimens.xml @@ -19,14 +19,12 @@      <!-- Recent Applications parameters -->      <!-- How far the thumbnail for a recent app appears from left edge -->      <dimen name="status_bar_recents_thumbnail_left_margin">110dp</dimen> -    <!-- Width of scrollable area in recents --> -    <dimen name="status_bar_recents_width">356dp</dimen>      <!-- Padding for text descriptions -->      <dimen name="status_bar_recents_text_description_padding">8dp</dimen>      <!-- Width of application label text -->      <dimen name="status_bar_recents_app_label_width">97dip</dimen>      <!-- Left margin of application label text --> -    <dimen name="status_bar_recents_app_label_left_margin">16dip</dimen> +    <dimen name="status_bar_recents_app_label_left_margin">8dip</dimen>      <!-- Margin between recents container and glow on the right -->      <dimen name="status_bar_recents_right_glow_margin">100dip</dimen>  </resources> diff --git a/packages/SystemUI/res/values-sw600dp/dimens.xml b/packages/SystemUI/res/values-sw600dp/dimens.xml index a5bea5c752cc..fe9245dda1fc 100644 --- a/packages/SystemUI/res/values-sw600dp/dimens.xml +++ b/packages/SystemUI/res/values-sw600dp/dimens.xml @@ -30,16 +30,19 @@      <dimen name="panel_float">56dp</dimen>      <!-- Recent Applications parameters --> -    <!-- Width of a recent app view, including all content --> -    <dimen name="status_bar_recents_thumbnail_view_width">156dp</dimen>      <!-- How far the thumbnail for a recent app appears from left edge --> -    <dimen name="status_bar_recents_thumbnail_left_margin">110dp</dimen> +    <dimen name="status_bar_recents_thumbnail_left_margin">121dp</dimen>      <!-- Upper width limit for application icon --> -    <dimen name="status_bar_recents_thumbnail_max_width">64dp</dimen> +    <dimen name="status_bar_recents_app_icon_max_width">64dp</dimen>      <!-- Upper height limit for application icon --> -    <dimen name="status_bar_recents_thumbnail_max_height">64dp</dimen> -    <!-- Width of scrollable area in recents --> -    <dimen name="status_bar_recents_width">356dp</dimen> +    <dimen name="status_bar_recents_app_icon_max_height">64dp</dimen> + +    <!-- Size of application icon --> +    <dimen name="status_bar_recents_thumbnail_width">245dp</dimen> +    <dimen name="status_bar_recents_thumbnail_height">144dp</dimen> + +    <!-- Width of recents panel --> +    <dimen name="status_bar_recents_width">600dp</dimen>      <!-- Padding for text descriptions -->      <dimen name="status_bar_recents_text_description_padding">8dp</dimen>      <!-- Size of application label text --> @@ -55,12 +58,6 @@      <!-- Margin between recents container and glow on the right -->      <dimen name="status_bar_recents_right_glow_margin">100dip</dimen> -    <!-- Offsets for rendering thumbnails over drawable recents_thumbnail_bg --> -    <dimen name="recents_thumbnail_bg_padding_left">15px</dimen> -    <dimen name="recents_thumbnail_bg_padding_top">8px</dimen> -    <dimen name="recents_thumbnail_bg_padding_right">12px</dimen> -    <dimen name="recents_thumbnail_bg_padding_bottom">8px</dimen> -      <!-- Where to place the app icon over the thumbnail -->      <dimen name="status_bar_recents_app_icon_left_margin">13dp</dimen>      <dimen name="status_bar_recents_app_icon_top_margin">13dp</dimen> diff --git a/packages/SystemUI/res/values/colors.xml b/packages/SystemUI/res/values/colors.xml index 5d14fa8e9698..4c222f9e19bc 100644 --- a/packages/SystemUI/res/values/colors.xml +++ b/packages/SystemUI/res/values/colors.xml @@ -22,5 +22,6 @@      <drawable name="ticker_background_color">#ff1d1d1d</drawable>      <drawable name="status_bar_background">#ff000000</drawable>      <drawable name="status_bar_recents_background">#b3000000</drawable> +    <drawable name="status_bar_recents_app_thumbnail_background">#88000000</drawable>      <drawable name="status_bar_notification_row_background_color">#ff000000</drawable>  </resources> diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml index f633825c5e26..d0ece6c67eb8 100644 --- a/packages/SystemUI/res/values/dimens.xml +++ b/packages/SystemUI/res/values/dimens.xml @@ -21,17 +21,21 @@      <!-- Recent Applications parameters -->      <!-- Upper width limit for application icon --> -    <dimen name="status_bar_recents_thumbnail_max_width">64dp</dimen> +    <dimen name="status_bar_recents_app_icon_max_width">64dp</dimen>      <!-- Upper height limit for application icon --> -    <dimen name="status_bar_recents_thumbnail_max_height">64dp</dimen> +    <dimen name="status_bar_recents_app_icon_max_height">64dp</dimen>      <!-- Where to place the app icon over the thumbnail -->      <dimen name="status_bar_recents_app_icon_left_margin">13dp</dimen>      <dimen name="status_bar_recents_app_icon_top_margin">13dp</dimen> +    <!-- Size of application thumbnail --> +    <dimen name="status_bar_recents_thumbnail_width">164dp</dimen> +    <dimen name="status_bar_recents_thumbnail_height">164dp</dimen> +      <!-- Size of application label text --> -    <dimen name="status_bar_recents_app_label_text_size">18dip</dimen> +    <dimen name="status_bar_recents_app_label_text_size">16dip</dimen>      <!-- Size of application description text --> -    <dimen name="status_bar_recents_app_description_text_size">18dip</dimen> +    <dimen name="status_bar_recents_app_description_text_size">16dip</dimen>      <!-- Size of fading edge for scroll effect -->      <dimen name="status_bar_recents_fading_edge_length">20dip</dimen>      <!-- Margin between recents container and glow on the right --> diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml index 7779703a0e7e..bad7e1fb1e8e 100644 --- a/packages/SystemUI/res/values/strings.xml +++ b/packages/SystemUI/res/values/strings.xml @@ -36,10 +36,10 @@      <string name="status_bar_please_disturb_button">Show notifications</string>      <!-- Title shown in recents popup for removing an application from the list --> -    <string name="status_bar_recent_remove_item_title">Remove</string> +    <string name="status_bar_recent_remove_item_title">Remove from list</string>      <!-- Title shown in recents popup for inspecting an application's properties --> -    <string name="status_bar_recent_inspect_item_title">Inspect</string> +    <string name="status_bar_recent_inspect_item_title">App info</string>      <!-- The label in the bar at the top of the status bar when there are no notifications           showing.  [CHAR LIMIT=40]--> diff --git a/packages/SystemUI/src/com/android/systemui/SwipeHelper.java b/packages/SystemUI/src/com/android/systemui/SwipeHelper.java index 6cfbc1b26768..14743f48aa74 100644 --- a/packages/SystemUI/src/com/android/systemui/SwipeHelper.java +++ b/packages/SystemUI/src/com/android/systemui/SwipeHelper.java @@ -307,6 +307,7 @@ public class SwipeHelper {                          dismissChild(mCurrView, childSwipedFastEnough ? velocity : 0f);                      } else {                          // snappity +                        mCallback.onDragCancelled(mCurrView);                          snapChild(mCurrView, velocity);                      }                  } @@ -325,5 +326,7 @@ public class SwipeHelper {          void onBeginDrag(View v);          void onChildDismissed(View v); + +        void onDragCancelled(View v);      }  } diff --git a/packages/SystemUI/src/com/android/systemui/recent/RecentsHorizontalScrollView.java b/packages/SystemUI/src/com/android/systemui/recent/RecentsHorizontalScrollView.java index 7ad7484a3f3d..85cde7c00da2 100644 --- a/packages/SystemUI/src/com/android/systemui/recent/RecentsHorizontalScrollView.java +++ b/packages/SystemUI/src/com/android/systemui/recent/RecentsHorizontalScrollView.java @@ -127,6 +127,11 @@ public class RecentsHorizontalScrollView extends HorizontalScrollView          // We do this so the underlying ScrollView knows that it won't get          // the chance to intercept events anymore          requestDisallowInterceptTouchEvent(true); +        v.setActivated(true); +    } + +    public void onDragCancelled(View v) { +        v.setActivated(false);      }      public View getChildAtPosition(MotionEvent ev) { diff --git a/packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java b/packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java index 233ed6ccb785..e59c10993093 100644 --- a/packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java +++ b/packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java @@ -84,12 +84,8 @@ public class RecentsPanelView extends RelativeLayout      private View mRecentsScrim;      private View mRecentsGlowView;      private ViewGroup mRecentsContainer; -    private Bitmap mGlowBitmap; -    // TODO: add these widgets attributes to the layout file -    private int mGlowBitmapPaddingLeftPx; -    private int mGlowBitmapPaddingTopPx; -    private int mGlowBitmapPaddingRightPx; -    private int mGlowBitmapPaddingBottomPx; +    private Bitmap mAppThumbnailBackground; +      private boolean mShowing;      private Choreographer mChoreo;      private View mRecentsDismissButton; @@ -129,7 +125,7 @@ public class RecentsPanelView extends RelativeLayout          }          public void setThumbnail(Bitmap thumbnail) { -            mThumbnail = compositeBitmap(mGlowBitmap, thumbnail); +            mThumbnail = compositeBitmap(mAppThumbnailBackground, thumbnail);          }          public Bitmap getThumbnail() { @@ -247,6 +243,16 @@ public class RecentsPanelView extends RelativeLayout          }      } +    public void hide(boolean animate) { +        mShowing = false; +        if (!animate) { +            setVisibility(View.GONE); +        } +        if (mBar != null) { +            mBar.animateCollapse(); +        } +    } +      public void handleShowBackground(boolean show) {          if (show) {              mRecentsScrim.setBackgroundResource(R.drawable.status_bar_recents_background); @@ -327,15 +333,12 @@ public class RecentsPanelView extends RelativeLayout          mIconDpi = xlarge ? DisplayMetrics.DENSITY_HIGH : res.getDisplayMetrics().densityDpi; -        mGlowBitmap = BitmapFactory.decodeResource(res, R.drawable.recents_thumbnail_bg); -        mGlowBitmapPaddingLeftPx = -                res.getDimensionPixelSize(R.dimen.recents_thumbnail_bg_padding_left); -        mGlowBitmapPaddingTopPx = -                res.getDimensionPixelSize(R.dimen.recents_thumbnail_bg_padding_top); -        mGlowBitmapPaddingRightPx = -                res.getDimensionPixelSize(R.dimen.recents_thumbnail_bg_padding_right); -        mGlowBitmapPaddingBottomPx = -                res.getDimensionPixelSize(R.dimen.recents_thumbnail_bg_padding_bottom); +        int width = (int) res.getDimension(R.dimen.status_bar_recents_thumbnail_width); +        int height = (int) res.getDimension(R.dimen.status_bar_recents_thumbnail_height); +        int color = res.getColor(R.drawable.status_bar_recents_app_thumbnail_background); +        mAppThumbnailBackground = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888); +        Canvas c = new Canvas(mAppThumbnailBackground); +        c.drawColor(color);      }      @Override @@ -570,6 +573,9 @@ public class RecentsPanelView extends RelativeLayout              mThumbnailLoader = null;          }          mActivityDescriptions = getRecentTasks(); +        for (ActivityDescription ad : mActivityDescriptions) { +            ad.setThumbnail(mAppThumbnailBackground); +        }          mListAdapter.notifyDataSetInvalidated();          if (mActivityDescriptions.size() > 0) {              if (DEBUG) Log.v(TAG, "Showing " + mActivityDescriptions.size() + " apps"); @@ -644,14 +650,8 @@ public class RecentsPanelView extends RelativeLayout              paint.setAntiAlias(true);              paint.setFilterBitmap(true);              paint.setAlpha(255); -            final int srcWidth = thumbnail.getWidth(); -            final int srcHeight = thumbnail.getHeight(); -            if (DEBUG) Log.v(TAG, "Source thumb: " + srcWidth + "x" + srcHeight); -            canvas.drawBitmap(thumbnail, -                    new Rect(0, 0, srcWidth-1, srcHeight-1), -                    new RectF(mGlowBitmapPaddingLeftPx, mGlowBitmapPaddingTopPx, -                            outBitmap.getWidth() - mGlowBitmapPaddingRightPx, -                            outBitmap.getHeight() - mGlowBitmapPaddingBottomPx), paint); +            canvas.drawBitmap(thumbnail, null, +                    new RectF(0, 0, outBitmap.getWidth(), outBitmap.getHeight()), paint);              canvas.setBitmap(null);          }          return outBitmap; @@ -664,15 +664,6 @@ public class RecentsPanelView extends RelativeLayout          mRecentsGlowView.setVisibility(items > 0 ? View.VISIBLE : View.GONE);      } -    public void hide(boolean animate) { -        if (!animate) { -            setVisibility(View.GONE); -        } -        if (mBar != null) { -            mBar.animateCollapse(); -        } -    } -      public void handleOnClick(View view) {          ActivityDescription ad = ((ViewHolder) view.getTag()).activityDescription;          final Context context = view.getContext(); diff --git a/packages/SystemUI/src/com/android/systemui/recent/RecentsVerticalScrollView.java b/packages/SystemUI/src/com/android/systemui/recent/RecentsVerticalScrollView.java index 1b6daa57c7c2..3acef0844593 100644 --- a/packages/SystemUI/src/com/android/systemui/recent/RecentsVerticalScrollView.java +++ b/packages/SystemUI/src/com/android/systemui/recent/RecentsVerticalScrollView.java @@ -142,6 +142,11 @@ public class RecentsVerticalScrollView extends ScrollView implements SwipeHelper          // We do this so the underlying ScrollView knows that it won't get          // the chance to intercept events anymore          requestDisallowInterceptTouchEvent(true); +        v.setActivated(true); +    } + +    public void onDragCancelled(View v) { +        v.setActivated(false);      }      public View getChildAtPosition(MotionEvent ev) { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java index 4ba514a0bf8f..3d23abe72739 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java @@ -404,7 +404,7 @@ public class PhoneStatusBar extends StatusBar {          // Recents Panel          boolean visible = false;          if (mRecentsPanel != null) { -            visible = mRecentsPanel.getVisibility() == View.VISIBLE; +            visible = mRecentsPanel.isShowing();              WindowManagerImpl.getDefault().removeView(mRecentsPanel);          } @@ -1125,20 +1125,22 @@ public class PhoneStatusBar extends StatusBar {          Slog.i(TAG, "DISABLE_BACK: " + (disableBack ? "yes" : "no"));          Slog.i(TAG, "DISABLE_NAVIGATION: " + (disableNavigation ? "yes" : "no")); -        if (disableNavigation && disableBack) { -            mNavigationBarView.setEnabled(false); -        } else { -            mNavigationBarView.getBackButton().setEnabled(!disableBack); -            mNavigationBarView.getHomeButton().setEnabled(!disableNavigation); -            mNavigationBarView.getRecentsButton().setEnabled(!disableNavigation); - -            if (disableNavigation) { -                // close recents if it's visible -                mHandler.removeMessages(MSG_CLOSE_RECENTS_PANEL); -                mHandler.sendEmptyMessage(MSG_CLOSE_RECENTS_PANEL); +        if (mNavigationBarView != null) { +            if (disableNavigation && disableBack) { +                mNavigationBarView.setEnabled(false); +            } else { +                mNavigationBarView.getBackButton().setEnabled(!disableBack); +                mNavigationBarView.getHomeButton().setEnabled(!disableNavigation); +                mNavigationBarView.getRecentsButton().setEnabled(!disableNavigation); + +                mNavigationBarView.setEnabled(true);              } +        } -            mNavigationBarView.setEnabled(true); +        if (disableNavigation) { +            // close recents if it's visible +            mHandler.removeMessages(MSG_CLOSE_RECENTS_PANEL); +            mHandler.sendEmptyMessage(MSG_CLOSE_RECENTS_PANEL);          }      } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NotificationRowLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NotificationRowLayout.java index 469b462ace48..e287b7a36d8d 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NotificationRowLayout.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NotificationRowLayout.java @@ -124,6 +124,9 @@ public class NotificationRowLayout extends ViewGroup implements SwipeHelper.Call          requestDisallowInterceptTouchEvent(true);      } +    public void onDragCancelled(View v) { +    } +      public View getChildAtPosition(MotionEvent ev) {          // find the view under the pointer, accounting for GONE views          final int count = getChildCount(); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/NotificationPanel.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/NotificationPanel.java index d9cb4e8678b9..4a1cafdcce6e 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/NotificationPanel.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/NotificationPanel.java @@ -28,6 +28,10 @@ import android.view.LayoutInflater;  import android.view.MotionEvent;  import android.view.View;  import android.view.ViewGroup; +import android.view.ViewTreeObserver; +import android.view.animation.AccelerateInterpolator; +import android.view.animation.DecelerateInterpolator; +import android.view.animation.Interpolator;  import android.widget.RelativeLayout;  import com.android.systemui.R; @@ -52,6 +56,8 @@ public class NotificationPanel extends RelativeLayout implements StatusBarPanel,      ViewGroup mContentParent;      TabletStatusBar mBar;      View mClearButton; +    static Interpolator sAccelerateInterpolator = new AccelerateInterpolator(); +    static Interpolator sDecelerateInterpolator = new DecelerateInterpolator();      // amount to slide mContentParent down by when mContentFrame is missing      float mContentFrameMissingTranslation; @@ -117,8 +123,13 @@ public class NotificationPanel extends RelativeLayout implements StatusBarPanel,                  mShowing = show;                  if (show) {                      setVisibility(View.VISIBLE); +                    // Don't start the animation until we've created the layer, which is done +                    // right before we are drawn +                    mContentParent.setLayerType(View.LAYER_TYPE_HARDWARE, null); +                    getViewTreeObserver().addOnPreDrawListener(mPreDrawListener); +                } else { +                    mChoreo.startAnimation(show);                  } -                mChoreo.startAnimation(show);              }          } else {              mShowing = show; @@ -127,6 +138,20 @@ public class NotificationPanel extends RelativeLayout implements StatusBarPanel,      }      /** +     * This is used only when we've created a hardware layer and are waiting until it's +     * been created in order to start the appearing animation. +     */ +    private ViewTreeObserver.OnPreDrawListener mPreDrawListener = +            new ViewTreeObserver.OnPreDrawListener() { +        @Override +        public boolean onPreDraw() { +            getViewTreeObserver().removeOnPreDrawListener(this); +            mChoreo.startAnimation(true); +            return true; +        } +    }; + +    /**       * Whether the panel is showing, or, if it's animating, whether it will be       * when the animation is done.       */ @@ -330,8 +355,8 @@ public class NotificationPanel extends RelativeLayout implements StatusBarPanel,          AnimatorSet mContentAnim;          // should group this into a multi-property animation -        final static int OPEN_DURATION = 300; -        final static int CLOSE_DURATION = 300; +        final static int OPEN_DURATION = 250; +        final static int CLOSE_DURATION = 250;          // the panel will start to appear this many px from the end          final int HYPERSPACE_OFFRAMP = 200; @@ -362,19 +387,15 @@ public class NotificationPanel extends RelativeLayout implements StatusBarPanel,              Animator posAnim = ObjectAnimator.ofFloat(mContentParent, "translationY",                      start, end); -            posAnim.setInterpolator(appearing -                    ? new android.view.animation.DecelerateInterpolator(1.0f) -                    : new android.view.animation.AccelerateInterpolator(1.0f)); +            posAnim.setInterpolator(appearing ? sDecelerateInterpolator : sAccelerateInterpolator);              if (mContentAnim != null && mContentAnim.isRunning()) {                  mContentAnim.cancel();              }              Animator fadeAnim = ObjectAnimator.ofFloat(mContentParent, "alpha", -                                mContentParent.getAlpha(), appearing ? 1.0f : 0.0f); -            fadeAnim.setInterpolator(appearing -                    ? new android.view.animation.AccelerateInterpolator(2.0f) -                    : new android.view.animation.DecelerateInterpolator(2.0f)); +                    appearing ? 1.0f : 0.0f); +            fadeAnim.setInterpolator(appearing ? sAccelerateInterpolator : sDecelerateInterpolator);              mContentAnim = new AnimatorSet();              mContentAnim @@ -389,8 +410,6 @@ public class NotificationPanel extends RelativeLayout implements StatusBarPanel,              if (DEBUG) Slog.d(TAG, "startAnimation(appearing=" + appearing + ")");              createAnimation(appearing); - -            mContentParent.setLayerType(View.LAYER_TYPE_HARDWARE, null);              mContentAnim.start();              mVisible = appearing; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java index 00f611f44d80..cc73d7bf2c17 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java @@ -306,7 +306,7 @@ public class TabletStatusBar extends StatusBar implements          mStatusBarView.setIgnoreChildren(2, mRecentButton, mRecentsPanel);          lp = new WindowManager.LayoutParams( -                ViewGroup.LayoutParams.MATCH_PARENT, +                (int) res.getDimension(R.dimen.status_bar_recents_width),                  ViewGroup.LayoutParams.MATCH_PARENT,                  WindowManager.LayoutParams.TYPE_STATUS_BAR_PANEL,                  WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN diff --git a/services/java/com/android/server/EventLogTags.logtags b/services/java/com/android/server/EventLogTags.logtags index 5429c0c72c93..f0b5958abc3e 100644 --- a/services/java/com/android/server/EventLogTags.logtags +++ b/services/java/com/android/server/EventLogTags.logtags @@ -137,3 +137,10 @@ option java_package com.android.server  # [ 8- 3] Detailed state ordinal (as defined by NetworkInfo.DetailedState)  # [ 2- 0] Network type (as defined by ConnectivityManager)  50020 connectivity_state_changed (custom|1|5) + + +# --------------------------- +# NetworkStatsService.java +# --------------------------- +51100 netstats_mobile_sample (iface_rx|2|2),(iface_tx|2|2),(uid_rx|2|2),(uid_tx|2|2) +51101 netstats_wifi_sample (iface_rx|2|2),(iface_tx|2|2),(uid_rx|2|2),(uid_tx|2|2) diff --git a/services/java/com/android/server/InputMethodManagerService.java b/services/java/com/android/server/InputMethodManagerService.java index bb831f51d07d..0e1a1e328723 100644 --- a/services/java/com/android/server/InputMethodManagerService.java +++ b/services/java/com/android/server/InputMethodManagerService.java @@ -655,7 +655,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub          List<InputMethodSubtype> enabledSubtypes =                  mSettings.getEnabledInputMethodSubtypeListLocked(imi);          if (allowsImplicitlySelectedSubtypes && enabledSubtypes.isEmpty()) { -            enabledSubtypes = getApplicableSubtypesLocked(mRes, getSubtypes(imi)); +            enabledSubtypes = getImplicitlyApplicableSubtypesLocked(mRes, imi);          }          return InputMethodSubtype.sort(mContext, 0, imi, enabledSubtypes);      } @@ -1668,13 +1668,13 @@ public class InputMethodManagerService extends IInputMethodManager.Stub      }      @Override -    public boolean setAdditionalInputMethodSubtypes(String imiId, InputMethodSubtype[] subtypes) { +    public void setAdditionalInputMethodSubtypes(String imiId, InputMethodSubtype[] subtypes) {          // By this IPC call, only a process which shares the same uid with the IME can add          // additional input method subtypes to the IME. -        if (TextUtils.isEmpty(imiId) || subtypes == null || subtypes.length == 0) return false; +        if (TextUtils.isEmpty(imiId) || subtypes == null || subtypes.length == 0) return;          synchronized (mMethodMap) {              final InputMethodInfo imi = mMethodMap.get(imiId); -            if (imi == null) return false; +            if (imi == null) return;              final PackageManager pm = mContext.getPackageManager();              final String[] packageInfos = pm.getPackagesForUid(Binder.getCallingUid());              if (packageInfos != null) { @@ -1688,12 +1688,12 @@ public class InputMethodManagerService extends IInputMethodManager.Stub                          } finally {                              Binder.restoreCallingIdentity(ident);                          } -                        return true; +                        return;                      }                  }              }          } -        return false; +        return;      }      private void setInputMethodWithSubtypeId(IBinder token, String id, int subtypeId) { @@ -1903,6 +1903,20 @@ public class InputMethodManagerService extends IInputMethodManager.Stub          return subtypes;      } + +    private static ArrayList<InputMethodSubtype> getOverridingImplicitlyEnabledSubtypes( +            InputMethodInfo imi, String mode) { +        ArrayList<InputMethodSubtype> subtypes = new ArrayList<InputMethodSubtype>(); +        final int subtypeCount = imi.getSubtypeCount(); +        for (int i = 0; i < subtypeCount; ++i) { +            final InputMethodSubtype subtype = imi.getSubtypeAt(i); +            if (subtype.overridesImplicitlyEnabledSubtype() && subtype.getMode().equals(mode)) { +                subtypes.add(subtype); +            } +        } +        return subtypes; +    } +      private boolean chooseNewDefaultIMELocked() {          List<InputMethodInfo> enabled = mSettings.getEnabledInputMethodListLocked();          if (enabled != null && enabled.size() > 0) { @@ -2357,8 +2371,9 @@ public class InputMethodManagerService extends IInputMethodManager.Stub          return NOT_A_SUBTYPE_ID;      } -    private static ArrayList<InputMethodSubtype> getApplicableSubtypesLocked( -            Resources res, List<InputMethodSubtype> subtypes) { +    private static ArrayList<InputMethodSubtype> getImplicitlyApplicableSubtypesLocked( +            Resources res, InputMethodInfo imi) { +        final List<InputMethodSubtype> subtypes = getSubtypes(imi);          final String systemLocale = res.getConfiguration().locale.toString();          if (TextUtils.isEmpty(systemLocale)) return new ArrayList<InputMethodSubtype>();          HashMap<String, InputMethodSubtype> applicableModeAndSubtypesMap = @@ -2366,6 +2381,19 @@ public class InputMethodManagerService extends IInputMethodManager.Stub          final int N = subtypes.size();          boolean containsKeyboardSubtype = false;          for (int i = 0; i < N; ++i) { +            // scan overriding implicitly enabled subtypes. +            InputMethodSubtype subtype = subtypes.get(i); +            if (subtype.overridesImplicitlyEnabledSubtype()) { +                final String mode = subtype.getMode(); +                if (!applicableModeAndSubtypesMap.containsKey(mode)) { +                    applicableModeAndSubtypesMap.put(mode, subtype); +                } +            } +        } +        if (applicableModeAndSubtypesMap.size() > 0) { +            return new ArrayList<InputMethodSubtype>(applicableModeAndSubtypesMap.values()); +        } +        for (int i = 0; i < N; ++i) {              InputMethodSubtype subtype = subtypes.get(i);              final String locale = subtype.getLocale();              final String mode = subtype.getMode(); @@ -2489,16 +2517,21 @@ public class InputMethodManagerService extends IInputMethodManager.Stub                  subtype = findLastResortApplicableSubtypeLocked(                          mRes, enabledSubtypes, mode, null, true);              } +            final ArrayList<InputMethodSubtype> overridingImplicitlyEnabledSubtypes = +                    getOverridingImplicitlyEnabledSubtypes(imi, mode); +            final ArrayList<InputMethodSubtype> subtypesForSearch = +                    overridingImplicitlyEnabledSubtypes.isEmpty() +                            ? getSubtypes(imi) : overridingImplicitlyEnabledSubtypes;              // 4. Search by the current subtype's locale from all subtypes.              if (subtype == null && mCurrentSubtype != null) {                  subtype = findLastResortApplicableSubtypeLocked( -                        mRes, getSubtypes(imi), mode, mCurrentSubtype.getLocale(), false); +                        mRes, subtypesForSearch, mode, mCurrentSubtype.getLocale(), false);              }              // 5. Search by the system locale from all subtypes.              // 6. Search the first enabled subtype matched with mode from all subtypes.              if (subtype == null) {                  subtype = findLastResortApplicableSubtypeLocked( -                        mRes, getSubtypes(imi), mode, null, true); +                        mRes, subtypesForSearch, mode, null, true);              }              if (subtype != null) {                  if (imiId.equals(mCurMethodId)) { @@ -2945,12 +2978,12 @@ public class InputMethodManagerService extends IInputMethodManager.Stub                      if (explicitlyEnabledSubtypes.size() == 0) {                          // If there are no explicitly enabled subtypes, applicable subtypes are                          // enabled implicitly. -                        InputMethodInfo ime = mMethodMap.get(imeId); +                        InputMethodInfo imi = mMethodMap.get(imeId);                          // If IME is enabled and no subtypes are enabled, applicable subtypes                          // are enabled implicitly, so needs to treat them to be enabled. -                        if (ime != null && ime.getSubtypeCount() > 0) { +                        if (imi != null && imi.getSubtypeCount() > 0) {                              List<InputMethodSubtype> implicitlySelectedSubtypes = -                                    getApplicableSubtypesLocked(mRes, getSubtypes(ime)); +                                    getImplicitlyApplicableSubtypesLocked(mRes, imi);                              if (implicitlySelectedSubtypes != null) {                                  final int N = implicitlySelectedSubtypes.size();                                  for (int i = 0; i < N; ++i) { diff --git a/services/java/com/android/server/NetworkManagementService.java b/services/java/com/android/server/NetworkManagementService.java index 85d8cece5401..14975118889b 100644 --- a/services/java/com/android/server/NetworkManagementService.java +++ b/services/java/com/android/server/NetworkManagementService.java @@ -1033,6 +1033,38 @@ public class NetworkManagementService extends INetworkManagementService.Stub          final NetworkStats stats = new NetworkStats(SystemClock.elapsedRealtime(), 6);          final NetworkStats.Entry entry = new NetworkStats.Entry(); +        final HashSet<String> knownIfaces = Sets.newHashSet(); +        final HashSet<String> activeIfaces = Sets.newHashSet(); + +        // collect any historical stats and active state +        // TODO: migrate to reading from single file +        if (mBandwidthControlEnabled) { +            for (String iface : fileListWithoutNull(mStatsXtIface)) { +                final File ifacePath = new File(mStatsXtIface, iface); + +                final long active = readSingleLongFromFile(new File(ifacePath, "active")); +                if (active == 1) { +                    knownIfaces.add(iface); +                    activeIfaces.add(iface); +                } else if (active == 0) { +                    knownIfaces.add(iface); +                } else { +                    continue; +                } + +                entry.iface = iface; +                entry.uid = UID_ALL; +                entry.set = SET_DEFAULT; +                entry.tag = TAG_NONE; +                entry.rxBytes = readSingleLongFromFile(new File(ifacePath, "rx_bytes")); +                entry.rxPackets = readSingleLongFromFile(new File(ifacePath, "rx_packets")); +                entry.txBytes = readSingleLongFromFile(new File(ifacePath, "tx_bytes")); +                entry.txPackets = readSingleLongFromFile(new File(ifacePath, "tx_packets")); + +                stats.addValues(entry); +            } +        } +          final ArrayList<String> values = Lists.newArrayList();          BufferedReader reader = null; @@ -1058,7 +1090,13 @@ public class NetworkManagementService extends INetworkManagementService.Stub                      entry.txBytes = Long.parseLong(values.get(9));                      entry.txPackets = Long.parseLong(values.get(10)); -                    stats.addValues(entry); +                    if (activeIfaces.contains(entry.iface)) { +                        // combine stats when iface is active +                        stats.combineValues(entry); +                    } else if (!knownIfaces.contains(entry.iface)) { +                        // add stats when iface is unknown +                        stats.addValues(entry); +                    }                  } catch (NumberFormatException e) {                      Slog.w(TAG, "problem parsing stats row '" + line + "': " + e);                  } @@ -1073,24 +1111,6 @@ public class NetworkManagementService extends INetworkManagementService.Stub              IoUtils.closeQuietly(reader);          } -        // splice in historical stats not reflected in mStatsIface -        if (mBandwidthControlEnabled) { -            for (String iface : fileListWithoutNull(mStatsXtIface)) { -                final File ifacePath = new File(mStatsXtIface, iface); - -                entry.iface = iface; -                entry.uid = UID_ALL; -                entry.set = SET_DEFAULT; -                entry.tag = TAG_NONE; -                entry.rxBytes = readSingleLongFromFile(new File(ifacePath, "rx_bytes")); -                entry.rxPackets = readSingleLongFromFile(new File(ifacePath, "rx_packets")); -                entry.txBytes = readSingleLongFromFile(new File(ifacePath, "tx_bytes")); -                entry.txPackets = readSingleLongFromFile(new File(ifacePath, "tx_packets")); - -                stats.combineValues(entry); -            } -        } -          return stats;      } diff --git a/services/java/com/android/server/PowerManagerService.java b/services/java/com/android/server/PowerManagerService.java index cbd986ff35fb..bbc26d689770 100644 --- a/services/java/com/android/server/PowerManagerService.java +++ b/services/java/com/android/server/PowerManagerService.java @@ -853,6 +853,14 @@ public class PowerManagerService extends IPowerManager.Stub                  if ((wl.flags & PowerManager.ACQUIRE_CAUSES_WAKEUP) != 0) {                      int oldWakeLockState = mWakeLockState;                      mWakeLockState = mLocks.reactivateScreenLocksLocked(); + +                    // Disable proximity sensor if if user presses power key while we are in the +                    // "waiting for proximity sensor to go negative" state. +                    if ((mWakeLockState & SCREEN_ON_BIT) != 0 +                            && mProximitySensorActive && mProximityWakeLockCount == 0) { +                        mProximitySensorActive = false; +                    } +                      if (mSpew) {                          Slog.d(TAG, "wakeup here mUserState=0x" + Integer.toHexString(mUserState)                                  + " mWakeLockState=0x" diff --git a/services/java/com/android/server/net/NetworkStatsService.java b/services/java/com/android/server/net/NetworkStatsService.java index e0dc96f99842..4d54fd4ea0f4 100644 --- a/services/java/com/android/server/net/NetworkStatsService.java +++ b/services/java/com/android/server/net/NetworkStatsService.java @@ -31,6 +31,8 @@ import static android.net.NetworkStats.SET_DEFAULT;  import static android.net.NetworkStats.SET_FOREGROUND;  import static android.net.NetworkStats.TAG_NONE;  import static android.net.NetworkStats.UID_ALL; +import static android.net.NetworkTemplate.buildTemplateMobileAll; +import static android.net.NetworkTemplate.buildTemplateWifi;  import static android.net.TrafficStats.UID_REMOVED;  import static android.provider.Settings.Secure.NETSTATS_NETWORK_BUCKET_DURATION;  import static android.provider.Settings.Secure.NETSTATS_NETWORK_MAX_HISTORY; @@ -76,6 +78,7 @@ import android.os.RemoteException;  import android.os.SystemClock;  import android.provider.Settings;  import android.telephony.TelephonyManager; +import android.util.EventLog;  import android.util.NtpTrustedTime;  import android.util.Slog;  import android.util.SparseIntArray; @@ -83,6 +86,7 @@ import android.util.TrustedTime;  import com.android.internal.os.AtomicFile;  import com.android.internal.util.Objects; +import com.android.server.EventLogTags;  import com.google.android.collect.Lists;  import com.google.android.collect.Maps;  import com.google.android.collect.Sets; @@ -387,7 +391,9 @@ public class NetworkStatsService extends INetworkStatsService.Stub {                      entry.uid = UID_ALL;                      entry.tag = TAG_NONE;                      entry.rxBytes = historyEntry.rxBytes; +                    entry.rxPackets = historyEntry.rxPackets;                      entry.txBytes = historyEntry.txBytes; +                    entry.txPackets = historyEntry.txPackets;                      stats.combineValues(entry);                  } @@ -716,6 +722,11 @@ public class NetworkStatsService extends INetworkStatsService.Stub {              Slog.v(TAG, "performPollLocked() took " + duration + "ms");          } +        // sample stats after detailed poll +        if (detailedPoll) { +            performSample(); +        } +          // finally, dispatch updated event to any listeners          final Intent updatedIntent = new Intent(ACTION_NETWORK_STATS_UPDATED);          updatedIntent.setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); @@ -809,6 +820,33 @@ public class NetworkStatsService extends INetworkStatsService.Stub {      }      /** +     * Sample recent statistics summary into {@link EventLog}. +     */ +    private void performSample() { +        // take sample as total over last 4 hours +        final long end = mTime.hasCache() ? mTime.currentTimeMillis() : System.currentTimeMillis(); +        final long start = end - (4 * HOUR_IN_MILLIS); + +        NetworkTemplate template = null; +        NetworkStats.Entry ifaceTotal = null; +        NetworkStats.Entry uidTotal = null; + +        // collect mobile sample +        template = buildTemplateMobileAll(getActiveSubscriberId(mContext)); +        ifaceTotal = getSummaryForNetwork(template, start, end).getTotal(ifaceTotal); +        uidTotal = getSummaryForAllUid(template, start, end, false).getTotal(uidTotal); +        EventLogTags.writeNetstatsMobileSample( +                ifaceTotal.rxBytes, ifaceTotal.txBytes, uidTotal.rxBytes, uidTotal.txBytes); + +        // collect wifi sample +        template = buildTemplateWifi(); +        ifaceTotal = getSummaryForNetwork(template, start, end).getTotal(ifaceTotal); +        uidTotal = getSummaryForAllUid(template, start, end, false).getTotal(uidTotal); +        EventLogTags.writeNetstatsWifiSample( +                ifaceTotal.rxBytes, ifaceTotal.txBytes, uidTotal.rxBytes, uidTotal.txBytes); +    } + +    /**       * Clean up {@link #mUidStats} after UID is removed.       */      private void removeUidLocked(int uid) { @@ -1249,6 +1287,12 @@ public class NetworkStatsService extends INetworkStatsService.Stub {          }      }; +    private static String getActiveSubscriberId(Context context) { +        final TelephonyManager telephony = (TelephonyManager) context.getSystemService( +                Context.TELEPHONY_SERVICE); +        return telephony.getSubscriberId(); +    } +      /**       * Key uniquely identifying a {@link NetworkStatsHistory} for a UID.       */ diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index 598220fd4c85..b4c5decae1e4 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -817,6 +817,20 @@ void SurfaceFlinger::handleWorkList()      mHwWorkListDirty = false;      HWComposer& hwc(graphicPlane(0).displayHardware().getHwComposer());      if (hwc.initCheck() == NO_ERROR) { + +        const DisplayHardware& hw(graphicPlane(0).displayHardware()); +        uint32_t flags = hw.getFlags(); +        if ((flags & DisplayHardware::SWAP_RECTANGLE) || +            (flags & DisplayHardware::BUFFER_PRESERVED)) +        { +            // we need to redraw everything (the whole screen) +            // NOTE: we could be more subtle here and redraw only +            // the area which will end-up in an overlay. But since this +            // shouldn't happen often, we invalidate everything. +            mDirtyRegion.set(hw.bounds()); +            mInvalidRegion = mDirtyRegion; +        } +          const Vector< sp<LayerBase> >& currentLayers(mVisibleLayersSortedByZ);          const size_t count = currentLayers.size();          hwc.createWorkList(count); diff --git a/services/tests/servicestests/src/com/android/server/NetworkManagementServiceTest.java b/services/tests/servicestests/src/com/android/server/NetworkManagementServiceTest.java index ecf78d9cef65..2a258661cfc9 100644 --- a/services/tests/servicestests/src/com/android/server/NetworkManagementServiceTest.java +++ b/services/tests/servicestests/src/com/android/server/NetworkManagementServiceTest.java @@ -106,6 +106,7 @@ public class NetworkManagementServiceTest extends AndroidTestCase {      public void testNetworkStatsSummaryDown() throws Exception {          stageFile(R.raw.net_dev_typical, new File(mTestProc, "net/dev")); +        stageLong(1L, new File(mTestProc, "net/xt_qtaguid/iface_stat/wlan0/active"));          stageLong(1024L, new File(mTestProc, "net/xt_qtaguid/iface_stat/wlan0/rx_bytes"));          stageLong(128L, new File(mTestProc, "net/xt_qtaguid/iface_stat/wlan0/rx_packets"));          stageLong(2048L, new File(mTestProc, "net/xt_qtaguid/iface_stat/wlan0/tx_bytes")); @@ -119,6 +120,7 @@ public class NetworkManagementServiceTest extends AndroidTestCase {      public void testNetworkStatsCombined() throws Exception {          stageFile(R.raw.net_dev_typical, new File(mTestProc, "net/dev")); +        stageLong(1L, new File(mTestProc, "net/xt_qtaguid/iface_stat/rmnet0/active"));          stageLong(10L, new File(mTestProc, "net/xt_qtaguid/iface_stat/rmnet0/rx_bytes"));          stageLong(20L, new File(mTestProc, "net/xt_qtaguid/iface_stat/rmnet0/rx_packets"));          stageLong(30L, new File(mTestProc, "net/xt_qtaguid/iface_stat/rmnet0/tx_bytes")); @@ -129,6 +131,18 @@ public class NetworkManagementServiceTest extends AndroidTestCase {                  2205L + 20L, 489339L + 30L, 2237L + 40L);      } +    public void testNetworkStatsCombinedInactive() throws Exception { +        stageFile(R.raw.net_dev_typical, new File(mTestProc, "net/dev")); +        stageLong(0L, new File(mTestProc, "net/xt_qtaguid/iface_stat/rmnet0/active")); +        stageLong(10L, new File(mTestProc, "net/xt_qtaguid/iface_stat/rmnet0/rx_bytes")); +        stageLong(20L, new File(mTestProc, "net/xt_qtaguid/iface_stat/rmnet0/rx_packets")); +        stageLong(30L, new File(mTestProc, "net/xt_qtaguid/iface_stat/rmnet0/tx_bytes")); +        stageLong(40L, new File(mTestProc, "net/xt_qtaguid/iface_stat/rmnet0/tx_packets")); + +        final NetworkStats stats = mService.getNetworkStatsSummary(); +        assertStatsEntry(stats, "rmnet0", UID_ALL, SET_DEFAULT, TAG_NONE, 10L, 20L, 30L, 40L); +    } +      public void testKernelTags() throws Exception {          assertEquals("0", tagToKernel(0x0));          assertEquals("214748364800", tagToKernel(0x32)); diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeIInputMethodManager.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeIInputMethodManager.java index 23e0ca1c389f..2a52888d2d29 100644 --- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeIInputMethodManager.java +++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeIInputMethodManager.java @@ -107,10 +107,9 @@ public class BridgeIInputMethodManager implements IInputMethodManager {      } -    public boolean setAdditionalInputMethodSubtypes(String arg0, InputMethodSubtype[] arg1) +    public void setAdditionalInputMethodSubtypes(String arg0, InputMethodSubtype[] arg1)              throws RemoteException {          // TODO Auto-generated method stub -        return false;      }      public boolean setCurrentInputMethodSubtype(InputMethodSubtype arg0) throws RemoteException { @@ -187,11 +186,4 @@ public class BridgeIInputMethodManager implements IInputMethodManager {          // TODO Auto-generated method stub          return null;      } - -    public boolean setAdditionalInputMethodSubtypes(IBinder arg0, InputMethodSubtype[] arg1) -            throws RemoteException { -        // TODO Auto-generated method stub -        return false; -    } -  } diff --git a/wifi/java/android/net/wifi/WpsConfiguration.java b/wifi/java/android/net/wifi/WpsConfiguration.java index 2e7689a5676d..0c2adfd714e6 100644 --- a/wifi/java/android/net/wifi/WpsConfiguration.java +++ b/wifi/java/android/net/wifi/WpsConfiguration.java @@ -46,16 +46,21 @@ public class WpsConfiguration implements Parcelable {      public Setup setup; +    /** @hide */      public String BSSID;      public String pin; +    /** @hide */      public IpAssignment ipAssignment; +    /** @hide */      public ProxySettings proxySettings; +    /** @hide */      public LinkProperties linkProperties; +    /** @hide */      public WpsConfiguration() {          setup = Setup.INVALID;          BSSID = null; @@ -65,6 +70,7 @@ public class WpsConfiguration implements Parcelable {          linkProperties = new LinkProperties();      } +    /** @hide */      public String toString() {          StringBuffer sbuf = new StringBuffer();          sbuf.append(" setup: ").append(setup.toString()); diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pConfig.java b/wifi/java/android/net/wifi/p2p/WifiP2pConfig.java index 2d5736323858..686d698847d4 100644 --- a/wifi/java/android/net/wifi/p2p/WifiP2pConfig.java +++ b/wifi/java/android/net/wifi/p2p/WifiP2pConfig.java @@ -28,11 +28,6 @@ import android.os.Parcel;  public class WifiP2pConfig implements Parcelable {      /** -     * Device name -     */ -    public String deviceName; - -    /**       * Device address       */      public String deviceAddress; @@ -53,6 +48,7 @@ public class WifiP2pConfig implements Parcelable {      /**       * Indicates whether the configuration is saved +     * @hide       */      public enum Persist {          SYSTEM_DEFAULT, @@ -60,6 +56,7 @@ public class WifiP2pConfig implements Parcelable {          NO      } +    /** @hide */      public Persist persist = Persist.SYSTEM_DEFAULT;      public WifiP2pConfig() { @@ -110,7 +107,6 @@ public class WifiP2pConfig implements Parcelable {      public String toString() {          StringBuffer sbuf = new StringBuffer(); -        sbuf.append("Device: ").append(deviceName);          sbuf.append("\n address: ").append(deviceAddress);          sbuf.append("\n wps: ").append(wpsConfig);          sbuf.append("\n groupOwnerIntent: ").append(groupOwnerIntent); @@ -132,7 +128,6 @@ public class WifiP2pConfig implements Parcelable {      /** Implement the Parcelable interface {@hide} */      public void writeToParcel(Parcel dest, int flags) { -        dest.writeString(deviceName);          dest.writeString(deviceAddress);          dest.writeParcelable(wpsConfig, flags);          dest.writeInt(groupOwnerIntent); @@ -144,7 +139,6 @@ public class WifiP2pConfig implements Parcelable {          new Creator<WifiP2pConfig>() {              public WifiP2pConfig createFromParcel(Parcel in) {                  WifiP2pConfig config = new WifiP2pConfig(); -                config.deviceName = in.readString();                  config.deviceAddress = in.readString();                  config.wpsConfig = (WpsConfiguration) in.readParcelable(null);                  config.groupOwnerIntent = in.readInt(); diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pGroup.java b/wifi/java/android/net/wifi/p2p/WifiP2pGroup.java index ca6e4d5122d6..14246b4fc3ec 100644 --- a/wifi/java/android/net/wifi/p2p/WifiP2pGroup.java +++ b/wifi/java/android/net/wifi/p2p/WifiP2pGroup.java @@ -69,7 +69,7 @@ public class WifiP2pGroup implements Parcelable {      }      /** -     * @param string formats supported include +     * @param supplicantEvent formats supported include       *       *  P2P-GROUP-STARTED p2p-wlan0-0 [client|GO] ssid="DIRECT-W8" freq=2437       *  [psk=2182b2e50e53f260d04f3c7b25ef33c965a3291b9b36b455a82d77fd82ca15bc| diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pInfo.java b/wifi/java/android/net/wifi/p2p/WifiP2pInfo.java index 9dc2fbfdd335..a02175e7b423 100644 --- a/wifi/java/android/net/wifi/p2p/WifiP2pInfo.java +++ b/wifi/java/android/net/wifi/p2p/WifiP2pInfo.java @@ -34,9 +34,11 @@ public class WifiP2pInfo implements Parcelable {      public InetAddress groupOwnerAddress; -    public WifiP2pInfo() { +    /** @hide */ +    WifiP2pInfo() {      } +    /** @hide */      public String toString() {          StringBuffer sbuf = new StringBuffer();          sbuf.append("groupFormed: ").append(groupFormed) diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pManager.java b/wifi/java/android/net/wifi/p2p/WifiP2pManager.java index 25daf1cecdcf..0bdd2697fb14 100644 --- a/wifi/java/android/net/wifi/p2p/WifiP2pManager.java +++ b/wifi/java/android/net/wifi/p2p/WifiP2pManager.java @@ -35,25 +35,64 @@ import com.android.internal.util.AsyncChannel;  import com.android.internal.util.Protocol;  /** - * This class provides the API for managing Wi-Fi p2p - * connectivity. Get an instance of this class by calling - * {@link android.content.Context#getSystemService(String) + * This class provides the API for managing Wi-Fi peer-to-peer connectivity. This lets an + * application discover available peers, setup connection to peers and query for the list of peers. + * When a p2p connection is formed over wifi, the device continues to maintain the uplink + * connection over mobile or any other available network for internet connectivity on the device. + * + * <p> The API is asynchronous and response to a request from an application is sent in the form + * of a {@link android.os.Message} on a {@link android.os.Handler} that needs to be initialized + * by the application right at the beginning before any p2p operations are performed via + * {@link #initialize}. + * + * <p> An application can request for the current list of peers using {@link #requestPeers}. The + * {@link #RESPONSE_PEERS} message on the handler indicates that the peer list is available. + * Use {@link #peersInResponse} to extract the peer device list upon the receiving the + * {@link #RESPONSE_PEERS} message. + * + * <p> If an application needs to initiate a discovery, use {@link #discoverPeers} and listen + * to {@link #WIFI_P2P_PEERS_CHANGED_ACTION} intent action to initiate a request to fetch + * list of peers with {@link #requestPeers}. An initiated discovery request from an application + * stays active until the device starts connecting to a peer or forms a p2p group. + * + * <p> An application can initiate a connection request to a peer through {@link #connect}. See + * {@link WifiP2pConfig} for details on setting up the configuration. For communication with legacy + * Wi-Fi devices that do not support p2p, an app can create a group using {@link #createGroup} + * which creates an access point whose details can be fetched with {@link #requestGroupInfo}. + * + * <p> After a successful group formation through {@link #createGroup} or through {@link #connect}, + * use {@link #requestConnectionInfo} to fetch the connection details. Connection information + * can be obtained with {@link #connectionInfoInResponse} on a {@link #RESPONSE_CONNECTION_INFO} + * message. The connection info {@link WifiP2pInfo} contains the address of the group owner + * {@link WifiP2pInfo#groupOwnerAddress} and a flag {@link #WifiP2pInfo#isGroupOwner} to indicate + * if the current device is a p2p group owner. A p2p client can thus communicate with + * the p2p group owner through a socket connection. + * + * <p> Android has no platform support for service discovery yet, so applications could + * run a service discovery protocol to discover services on the peer-to-peer netework. + * + * <p class="note"><strong>Note:</strong> + * Registering an application handler with {@link #initialize} requires the permissions + * {@link android.Manifest.permission#ACCESS_WIFI_STATE} and + * {@link android.Manifest.permission#CHANGE_WIFI_STATE} to perform any further peer-to-peer + * operations. + * + * Get an instance of this class by calling {@link android.content.Context#getSystemService(String)   * Context.getSystemService(Context.WIFI_P2P_SERVICE)}.   * - * It deals with the following: - * <ul> - * <li>Wi-Fi peer discovery and connection setup. Allows applications to initiate a discovery to - * find available peers and then setup a connection </li> - * <li>Configuration and status query. Allows applications to fetch the current list - * of available and connected peers and query connection status </li> - * <li>Intent actions that are broadcast to track operations - * on a p2p connection</li> - * </ul> + * {@see WifiP2pConfig} + * {@see WifiP2pInfo} + * {@see WifiP2pGroup} + * {@see WifiP2pDevice} + * {@see WifiP2pDeviceList}   * @hide   */  public class WifiP2pManager {      /** -     * Broadcast intent action to indicate whether Wi-Fi p2p is enabled or disabled. +     * Broadcast intent action to indicate whether Wi-Fi p2p is enabled or disabled. An +     * extra {@link #EXTRA_WIFI_STATE} provides the state information as int. +     * +     * @see #EXTRA_WIFI_STATE       */      @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)      public static final String WIFI_P2P_STATE_CHANGED_ACTION = @@ -72,7 +111,6 @@ public class WifiP2pManager {       * Wi-Fi p2p is disabled.       *       * @see #WIFI_P2P_STATE_CHANGED_ACTION -     * @see #getWifiP2pState()       */      public static final int WIFI_P2P_STATE_DISABLED = 1; @@ -80,14 +118,16 @@ public class WifiP2pManager {       * Wi-Fi p2p is enabled.       *       * @see #WIFI_P2P_STATE_CHANGED_ACTION -     * @see #getWifiP2pState()       */      public static final int WIFI_P2P_STATE_ENABLED = 2;      /**       * Broadcast intent action indicating that the state of Wi-Fi p2p connectivity -     * has changed. One extra provides the new state -     * in the form of a {@link android.net.NetworkInfo} object. +     * has changed. One extra {@link #EXTRA_WIFI_P2P_INFO} provides the p2p connection info in +     * the form of a {@link WifiP2pInfo} object. Another extra {@link #EXTRA_NETWORK_INFO} provides +     * the network info in the form of a {@link android.net.NetworkInfo}. +     * +     * @see #EXTRA_WIFI_P2P_INFO       * @see #EXTRA_NETWORK_INFO       */      @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) @@ -124,7 +164,8 @@ public class WifiP2pManager {      public static final String EXTRA_LINK_CAPABILITIES = "linkCapabilities";      /** -     * Broadcast intent action indicating that the available peer list has changed +     * Broadcast intent action indicating that the available peer list has changed. Fetch +     * the changed list of peers with {@link #requestPeers}       */      @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)      public static final String WIFI_P2P_PEERS_CHANGED_ACTION = @@ -134,6 +175,7 @@ public class WifiP2pManager {       * Activity Action: Pick a Wi-Fi p2p network to connect to.       * <p>Input: Nothing.       * <p>Output: Nothing. +     * @hide       */      @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)      public static final String ACTION_PICK_WIFI_P2P_NETWORK = @@ -141,47 +183,169 @@ public class WifiP2pManager {      IWifiP2pManager mService; -    /* AsyncChannel notifications to apps */ -    public static final int HANDLER_CONNECTION = AsyncChannel.CMD_CHANNEL_HALF_CONNECTED; +    /** +     * Message {@link android.os.Message#what} sent on the application handler specified +     * at {@link #initialize} indicating the asynchronous channel has disconnected. An +     * application could choose to reconnect with {@link #initialize} +     */      public static final int HANDLER_DISCONNECTION = AsyncChannel.CMD_CHANNEL_DISCONNECTED;      private static final int BASE = Protocol.BASE_WIFI_P2P_MANAGER; +    /** @hide */      public static final int ENABLE_P2P                              = BASE + 1; +    /** @hide */      public static final int ENABLE_P2P_FAILED                       = BASE + 2; +    /** @hide */      public static final int ENABLE_P2P_SUCCEEDED                    = BASE + 3; +    /** @hide */      public static final int DISABLE_P2P                             = BASE + 4; +    /** @hide */      public static final int DISABLE_P2P_FAILED                      = BASE + 5; +    /** @hide */      public static final int DISABLE_P2P_SUCCEEDED                   = BASE + 6; +    /** @hide */      public static final int DISCOVER_PEERS                          = BASE + 7; + +    /** +     * Message {@link android.os.Message#what} value indicating that the {@link #discoverPeers} +     * operation failed. +     * <p> The reason for failure could be one of {@link #P2P_UNSUPPORTED}, {@link #P2P_DISABLED} +     * or {@link #ALREADY_IN_EFFECT} +     */      public static final int DISCOVER_PEERS_FAILED                   = BASE + 8; +    /** +     * Message {@link android.os.Message#what} value indicating that the {@link #discoverPeers} +     * operation succeeded. +     * <p> The application can register for {@link #WIFI_P2P_PEERS_CHANGED_ACTION} intent +     * to listen for changes in the peer list as a result of the discovery process. +     */      public static final int DISCOVER_PEERS_SUCCEEDED                = BASE + 9; +    /** @hide */      public static final int CONNECT                                 = BASE + 10; + +    /** +     * Message {@link android.os.Message#what} value indicating that the {@link #connect} +     * operation failed. +     * <p> The reason for failure could be one of {@link #P2P_UNSUPPORTED}, {@link #P2P_DISABLED} +     * or {@link #ALREADY_IN_EFFECT} +     */      public static final int CONNECT_FAILED                          = BASE + 11; +    /** +     * Message {@link android.os.Message#what} value indicating that the {@link #connect} +     * operation succeeded. +     * <p> The application can register for {@link #WIFI_P2P_CONNECTION_CHANGED_ACTION} intent +     * to listen for connectivity change as a result of the connect operation +     */      public static final int CONNECT_SUCCEEDED                       = BASE + 12; +    /** @hide */      public static final int CREATE_GROUP                            = BASE + 13; + +    /** +     * Message {@link android.os.Message#what} value indicating that the {@link #createGroup} +     * operation failed. +     * <p> The reason for failure could be one of {@link #P2P_UNSUPPORTED}, {@link #P2P_DISABLED} +     * or {@link #ALREADY_IN_EFFECT} +     */      public static final int CREATE_GROUP_FAILED                     = BASE + 14; +    /** +     * Message {@link android.os.Message#what} value indicating that the {@link #createGroup} +     * operation succeeded. +     * <p> The application can request the group details with {@link #requestGroupInfo} +     */      public static final int CREATE_GROUP_SUCCEEDED                  = BASE + 15; +    /** @hide */      public static final int REMOVE_GROUP                            = BASE + 16; +    /** +     * Message {@link android.os.Message#what} value indicating that the {@link #removeGroup} +     * operation failed. +     * <p> The reason for failure could be one of {@link #P2P_UNSUPPORTED}, {@link #P2P_DISABLED} +     * or {@link #ALREADY_IN_EFFECT} +     */      public static final int REMOVE_GROUP_FAILED                     = BASE + 17; +    /** +     * Message {@link android.os.Message#what} value indicating that the {@link #removeGroup} +     * operation succeeded. +     */      public static final int REMOVE_GROUP_SUCCEEDED                  = BASE + 18; +    /** +     * Supported {@link android.os.Message#arg1} value on the following response messages: +     * {@link #DISCOVER_PEERS_FAILED}, {@link #CONNECT_FAILED}, {@link #CREATE_GROUP_FAILED} +     * and {@link #REMOVE_GROUP_FAILED} +     * +     * <p> This indicates that the reason for failure is because p2p is unsupported on the +     * device +     */ +    public static final int P2P_UNSUPPORTED     = 1; + +    /** +     * Supported {@link android.os.Message#arg1} value on the following response messages: +     * {@link #DISCOVER_PEERS_FAILED}, {@link #CONNECT_FAILED}, {@link #CREATE_GROUP_FAILED} +     * and {@link #REMOVE_GROUP_FAILED} +     * +     * <p> This indicates that the reason for failure is because p2p is currently disabled +     * by the user +     */ +    public static final int P2P_DISABLED        = 2; + +    /** +     * Supported {@link android.os.Message#arg1} value on the following response messages: +     * {@link #DISCOVER_PEERS_FAILED}, {@link #CONNECT_FAILED}, {@link #CREATE_GROUP_FAILED} +     * and {@link #REMOVE_GROUP_FAILED} +     * +     * <p> This indicates that the reason for failure is because the operation is already in +     * effect +     */ +    public static final int ALREADY_IN_EFFECT   = 3; + + +    /** @hide */      public static final int REQUEST_PEERS                           = BASE + 19; +    /** +     * Message {@link android.os.Message#what} delivered on the application hander +     * in response to a {@link #requestPeers} call from the application. +     * +     * <p> Extract a {@link WifiP2pDeviceList} object by calling {@link #peersInResponse} +     * on the message object +     */      public static final int RESPONSE_PEERS                          = BASE + 20; +    /** @hide */      public static final int REQUEST_CONNECTION_INFO                 = BASE + 21; + +    /** +     * Message {@link android.os.Message#what} delivered on the application hander +     * in response to a {@link #requestConnectionInfo} call from the application. +     * +     * <p> Extract a {@link WifiP2pInfo} object by calling {@link #connectionInfoInResponse} +     * on the message object +     */      public static final int RESPONSE_CONNECTION_INFO                = BASE + 22; -    /* arg1 values on response messages from the framework */ -    public static final int P2P_UNSUPPORTED     = 1; +    /** @hide */ +    public static final int REQUEST_GROUP_INFO                      = BASE + 23; + +    /** +     * Message {@link android.os.Message#what} delivered on the application hander +     * in response to a {@link #requestGroupInfo} call from the application. +     * +     * <p> Extract a {@link WifiP2pGroup} object by calling {@link #groupInfoInResponse} +     * on the message object +     */ + +    public static final int RESPONSE_GROUP_INFO                     = BASE + 24; +    /** @hide */      public static final int WPS_PBC                                 = BASE + 23; +    /** @hide */      public static final int WPS_PIN                                 = BASE + 24; +    /** @hide */      public static final int WPS_PIN_AVAILABLE                       = BASE + 25;      /** @@ -199,7 +363,8 @@ public class WifiP2pManager {      /**       * A channel that connects the application handler to the Wifi framework. -     * All p2p operations are performed on a channel. +     * Most p2p operations require a Channel as an argument. An instance of Channel is obtained +     * by doing a call on {@link #initialize}       */      public class Channel {          Channel(AsyncChannel c) { @@ -210,10 +375,17 @@ public class WifiP2pManager {      /**       * Registers the application handler with the Wi-Fi framework. This function -     * must be the first to be called before any p2p control or query operations can be performed. +     * must be the first to be called before any p2p operations are performed. +     * +     * <p class="note"><strong>Note:</strong> +     * The handler registered with the framework should only handle messages +     * with {@link android.os.Message#what} values defined in this file. Adding application +     * specific private {@link android.os.Message#what} types should be done on a seperate handler +     *       * @param srcContext is the context of the source -     * @param srcHandler is the handler on which the source receives messages -     * @return Channel instance that is necessary for performing p2p operations +     * @param srcHandler is the handler on which the source will receive message responses +     * asynchronously +     * @return Channel instance that is necessary for performing any further p2p operations       */      public Channel initialize(Context srcContext, Handler srcHandler) {          Messenger messenger = getMessenger(); @@ -229,6 +401,7 @@ public class WifiP2pManager {          }      } +    /** @hide */      public boolean isP2pSupported() {          try {              return mService.isP2pSupported(); @@ -240,6 +413,7 @@ public class WifiP2pManager {      /**       * Sends in a request to the system to enable p2p. This will pop up a dialog       * to the user and upon authorization will enable p2p. +     * @hide       */      public void enableP2p(Channel c) {          if (c == null) return; @@ -249,6 +423,7 @@ public class WifiP2pManager {      /**       * Sends in a request to the system to disable p2p. This will pop up a dialog       * to the user and upon authorization will enable p2p. +     * @hide       */      public void disableP2p(Channel c) {          if (c == null) return; @@ -256,7 +431,22 @@ public class WifiP2pManager {      }      /** -     * Initiates peer discovery +     * Initiate peer discovery. A discovery process involves scanning for available Wi-Fi peers +     * for the purpose of establishing a connection. +     * +     * <p> The function call immediately returns after sending a discovery request +     * to the framework. The application handler is notified of a success or failure to initiate +     * discovery with {@link #DISCOVER_PEERS_SUCCEEDED} or {@link #DISCOVER_PEERS_FAILED}. +     * +     * <p> The discovery remains active until a connection is initiated or +     * a p2p group is formed. Register for {@link #WIFI_P2P_PEERS_CHANGED_ACTION} intent to +     * determine when the framework notifies of a change as peers are discovered. +     * +     * <p> Upon receiving a {@link #WIFI_P2P_PEERS_CHANGED_ACTION} intent, an application +     * can request for the list of peers using {@link #requestPeers} which will deliver a +     * {@link #RESPONSE_PEERS} message on the application handler. The application can then +     * extract a {@link WifiP2pDeviceList} object by calling {@link #peersInResponse} +     * on the message.       */      public void discoverPeers(Channel c) {          if (c == null) return; @@ -264,9 +454,23 @@ public class WifiP2pManager {      }      /** -     * Start a p2p connection +     * Start a p2p connection to a device with the specified configuration. +     * +     * <p> The function call immediately returns after sending a connection request +     * to the framework. The application handler is notified of a success or failure to initiate +     * connectivity with {@link #CONNECT_SUCCEEDED} or {@link #CONNECT_FAILED}.       * -     * @param peer Configuration described in a {@link WifiP2pConfig} object. +     * <p> Register for {@link #WIFI_P2P_CONNECTION_CHANGED_ACTION} intent to +     * determine when the framework notifies of a change in connectivity. +     * +     * <p> If the current device is not part of a p2p group, a connect request initiates +     * a group negotiation with the peer. +     * +     * <p> If the current device is part of an existing p2p group or has created +     * a p2p group with {@link #createGroup}, an invitation to join the group is sent to +     * the peer device. +     * +     * @param config options as described in {@link WifiP2pConfig} class.       */      public void connect(Channel c, WifiP2pConfig config) {          if (c == null) return; @@ -274,8 +478,20 @@ public class WifiP2pManager {      }      /** -     * Create a p2p group. This is essentially an access point that can accept -     * client connections. +     * Create a p2p group with the current device as the group owner. This essentially creates +     * an access point that can accept connections from legacy clients as well as other p2p +     * devices. +     * <p> For p2p operation, this would normally not be used unless the current device needs +     * to form a p2p connection with a legacy client +     * +     * <p> The function call immediately returns after sending a group creation request +     * to the framework. The application handler is notified of a success or failure to create +     * group with {@link #CREATE_GROUP_SUCCEEDED} or {@link #CREATE_GROUP_FAILED}. +     * +     * <p> Application can request for the group details with {@link #requestGroupInfo} which will +     * deliver a {@link #RESPONSE_GROUP_INFO} message on the application handler. The application +     * can then extract a {@link WifiP2pGroup} object by calling {@link #groupInfoInResponse} +     * on the message.       */      public void createGroup(Channel c) {          if (c == null) return; @@ -283,8 +499,11 @@ public class WifiP2pManager {      }      /** -     * Remove the current group. This also removes the p2p interface created -     * during group formation. +     * Remove the current p2p group. +     * +     * <p> The function call immediately returns after sending a group removal request +     * to the framework. The application handler is notified of a success or failure to remove +     * a group with {@link #REMOVE_GROUP_SUCCEEDED} or {@link #REMOVE_GROUP_FAILED}.       */      public void removeGroup(Channel c) {          if (c == null) return; @@ -292,8 +511,9 @@ public class WifiP2pManager {      }      /** -     * Request the list of peers. This returns a RESPONSE_PEERS on the source -     * handler. +     * Request the current list of peers. This returns a {@link #RESPONSE_PEERS} on the application +     * handler. The {@link #RESPONSE_PEERS} message on the handler indicates that the peer list is +     * available. Use {@link #peersInResponse} to extract {@link WifiP2pDeviceList} from the message       */      public void requestPeers(Channel c) {          if (c == null) return; @@ -301,15 +521,18 @@ public class WifiP2pManager {      }      /** -     * Fetch device list from a RESPONSE_PEERS message +     * Upon receiving a {@link #RESPONSE_PEERS} on the application handler, an application +     * can extract the peer device list using this function.       */      public WifiP2pDeviceList peersInResponse(Message msg) {          return (WifiP2pDeviceList) msg.obj;      }      /** -     * Request device connection info. This returns a RESPONSE_CONNECTION_INFO on -     * the source handler. +     * Request device connection info. This returns a {@link #RESPONSE_CONNECTION_INFO} on +     * the application handler. The {@link #RESPONSE_CONNECTION_INFO} message on the handler +     * indicates that connection info is available. Use {@link #connectionInfoInResponse} to +     * extract {@link WifiP2pInfo} from the message.       */      public void requestConnectionInfo(Channel c) {          if (c == null) return; @@ -317,12 +540,31 @@ public class WifiP2pManager {      }      /** -     * Fetch p2p connection status from a RESPONSE_CONNECTION_INFO message +     * Upon receiving a {@link #RESPONSE_CONNECTION_INFO} on the application handler, an application +     * can extract the connection info using this function.       */      public WifiP2pInfo connectionInfoInResponse(Message msg) {          return (WifiP2pInfo) msg.obj;      } +    /** +     * Request p2p group info. This returns a {@link #RESPONSE_GROUP_INFO} on +     * the application handler. The {@link #RESPONSE_GROUP_INFO} message on the handler +     * indicates that group info is available. Use {@link #groupInfoInResponse} to +     * extract {@link WifiP2pGroup} from the message. +     */ +    public void requestGroupInfo(Channel c) { +        if (c == null) return; +        c.mAsyncChannel.sendMessage(REQUEST_GROUP_INFO); +    } + +    /** +     * Upon receiving a {@link #RESPONSE_GROUP_INFO} on the application handler, an application +     * can extract the group info using this function. +     */ +    public WifiP2pGroup groupInfoInResponse(Message msg) { +        return (WifiP2pGroup) msg.obj; +    }      /**       * Get a reference to WifiP2pService handler. This is used to establish @@ -339,7 +581,6 @@ public class WifiP2pManager {          }      } -      /**       * Setup DNS connectivity on the current process to the connected Wi-Fi p2p peers       * |