Merge "ConnectionService API has only one completed callback (1/3)" into lmp-dev
diff --git a/api/current.txt b/api/current.txt
index d3697e6..ab134f3 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -8595,19 +8595,26 @@
}
public class LauncherApps {
+ method public void addCallback(android.content.pm.LauncherApps.Callback);
+ method public void addCallback(android.content.pm.LauncherApps.Callback, android.os.Handler);
method public void addOnAppsChangedCallback(android.content.pm.LauncherApps.OnAppsChangedCallback);
method public void addOnAppsChangedCallback(android.content.pm.LauncherApps.OnAppsChangedCallback, android.os.Handler);
method public java.util.List<android.content.pm.LauncherActivityInfo> getActivityList(java.lang.String, android.os.UserHandle);
+ method public boolean isActivityEnabled(android.content.ComponentName, android.os.UserHandle);
method public boolean isActivityEnabledForProfile(android.content.ComponentName, android.os.UserHandle);
+ method public boolean isPackageEnabled(java.lang.String, android.os.UserHandle);
method public boolean isPackageEnabledForProfile(java.lang.String, android.os.UserHandle);
+ method public void removeCallback(android.content.pm.LauncherApps.Callback);
method public void removeOnAppsChangedCallback(android.content.pm.LauncherApps.OnAppsChangedCallback);
method public android.content.pm.LauncherActivityInfo resolveActivity(android.content.Intent, android.os.UserHandle);
method public void showAppDetailsForProfile(android.content.ComponentName, android.os.UserHandle, android.graphics.Rect, android.os.Bundle);
method public void startActivityForProfile(android.content.ComponentName, android.os.UserHandle, android.graphics.Rect, android.os.Bundle);
+ method public void startAppDetailsActivity(android.content.ComponentName, android.os.UserHandle, android.graphics.Rect, android.os.Bundle);
+ method public void startMainActivity(android.content.ComponentName, android.os.UserHandle, android.graphics.Rect, android.os.Bundle);
}
- public static abstract class LauncherApps.OnAppsChangedCallback {
- ctor public LauncherApps.OnAppsChangedCallback();
+ public static abstract class LauncherApps.Callback {
+ ctor public LauncherApps.Callback();
method public abstract void onPackageAdded(java.lang.String, android.os.UserHandle);
method public abstract void onPackageChanged(java.lang.String, android.os.UserHandle);
method public abstract void onPackageRemoved(java.lang.String, android.os.UserHandle);
@@ -8615,6 +8622,10 @@
method public abstract void onPackagesUnavailable(java.lang.String[], android.os.UserHandle, boolean);
}
+ public static abstract class LauncherApps.OnAppsChangedCallback extends android.content.pm.LauncherApps.Callback {
+ ctor public LauncherApps.OnAppsChangedCallback();
+ }
+
public class PackageInfo implements android.os.Parcelable {
ctor public PackageInfo();
method public int describeContents();
@@ -16612,33 +16623,41 @@
method public void adjustVolume(int, int);
method public android.media.routing.MediaRouter.Delegate createMediaRouterDelegate();
method public boolean dispatchMediaButtonEvent(android.view.KeyEvent);
+ method public android.media.session.MediaController.AudioInfo getAudioInfo();
method public android.os.Bundle getExtras();
method public long getFlags();
method public android.app.PendingIntent getLaunchActivity();
method public android.media.MediaMetadata getMetadata();
method public java.lang.String getPackageName();
method public android.media.session.PlaybackState getPlaybackState();
- method public java.util.List<android.media.session.MediaSession.Track> getQueue();
+ method public java.util.List<android.media.session.MediaSession.Item> getQueue();
method public java.lang.CharSequence getQueueTitle();
method public int getRatingType();
method public android.media.session.MediaSession.Token getSessionToken();
method public android.media.session.MediaController.TransportControls getTransportControls();
- method public android.media.session.MediaController.VolumeInfo getVolumeInfo();
method public void removeCallback(android.media.session.MediaController.Callback);
method public void sendCommand(java.lang.String, android.os.Bundle, android.os.ResultReceiver);
method public void setVolumeTo(int, int);
}
+ public static final class MediaController.AudioInfo {
+ method public android.media.AudioAttributes getAudioAttributes();
+ method public int getCurrentVolume();
+ method public int getMaxVolume();
+ method public int getVolumeControl();
+ method public int getVolumeType();
+ }
+
public static abstract class MediaController.Callback {
ctor public MediaController.Callback();
+ method public void onAudioInfoChanged(android.media.session.MediaController.AudioInfo);
method public void onExtrasChanged(android.os.Bundle);
method public void onMetadataChanged(android.media.MediaMetadata);
method public void onPlaybackStateChanged(android.media.session.PlaybackState);
- method public void onQueueChanged(java.util.List<android.media.session.MediaSession.Track>);
+ method public void onQueueChanged(java.util.List<android.media.session.MediaSession.Item>);
method public void onQueueTitleChanged(java.lang.CharSequence);
method public void onSessionDestroyed();
method public void onSessionEvent(java.lang.String, android.os.Bundle);
- method public void onVolumeInfoChanged(android.media.session.MediaController.VolumeInfo);
}
public final class MediaController.TransportControls {
@@ -16652,20 +16671,12 @@
method public void sendCustomAction(android.media.session.PlaybackState.CustomAction, android.os.Bundle);
method public void sendCustomAction(java.lang.String, android.os.Bundle);
method public void setRating(android.media.Rating);
+ method public void skipToItem(long);
method public void skipToNext();
method public void skipToPrevious();
- method public void skipToTrack(long);
method public void stop();
}
- public static final class MediaController.VolumeInfo {
- method public android.media.AudioAttributes getAudioAttributes();
- method public int getCurrentVolume();
- method public int getMaxVolume();
- method public int getVolumeControl();
- method public int getVolumeType();
- }
-
public final class MediaSession {
ctor public MediaSession(android.content.Context, java.lang.String);
method public android.media.session.MediaController getController();
@@ -16685,7 +16696,7 @@
method public void setPlaybackState(android.media.session.PlaybackState);
method public void setPlaybackToLocal(android.media.AudioAttributes);
method public void setPlaybackToRemote(android.media.VolumeProvider);
- method public void setQueue(java.util.List<android.media.session.MediaSession.Track>);
+ method public void setQueue(java.util.List<android.media.session.MediaSession.Item>);
method public void setQueueTitle(java.lang.CharSequence);
field public static final int FLAG_HANDLES_MEDIA_BUTTONS = 1; // 0x1
field public static final int FLAG_HANDLES_TRANSPORT_CONTROLS = 2; // 0x2
@@ -16706,19 +16717,13 @@
method public void onRewind();
method public void onSeekTo(long);
method public void onSetRating(android.media.Rating);
+ method public void onSkipToItem(long);
method public void onSkipToNext();
method public void onSkipToPrevious();
- method public void onSkipToTrack(long);
method public void onStop();
}
- public static final class MediaSession.Token implements android.os.Parcelable {
- method public int describeContents();
- method public void writeToParcel(android.os.Parcel, int);
- field public static final android.os.Parcelable.Creator CREATOR;
- }
-
- public static final class MediaSession.Track implements android.os.Parcelable {
+ public static final class MediaSession.Item implements android.os.Parcelable {
method public int describeContents();
method public android.os.Bundle getExtras();
method public long getId();
@@ -16729,20 +16734,25 @@
field public static final int UNKNOWN_ID = -1; // 0xffffffff
}
- public static final class MediaSession.Track.Builder {
- ctor public MediaSession.Track.Builder(android.media.MediaMetadata, long, android.net.Uri);
- method public android.media.session.MediaSession.Track build();
- method public android.media.session.MediaSession.Track.Builder setExtras(android.os.Bundle);
+ public static final class MediaSession.Item.Builder {
+ ctor public MediaSession.Item.Builder(android.media.MediaMetadata, long, android.net.Uri);
+ method public android.media.session.MediaSession.Item build();
+ method public android.media.session.MediaSession.Item.Builder setExtras(android.os.Bundle);
+ }
+
+ public static final class MediaSession.Token implements android.os.Parcelable {
+ method public int describeContents();
+ method public void writeToParcel(android.os.Parcel, int);
+ field public static final android.os.Parcelable.Creator CREATOR;
}
public final class MediaSessionManager {
- method public void addActiveSessionsListener(android.media.session.MediaSessionManager.SessionListener, android.content.ComponentName);
+ method public void addOnActiveSessionsChangedListener(android.media.session.MediaSessionManager.OnActiveSessionsChangedListener, android.content.ComponentName);
method public java.util.List<android.media.session.MediaController> getActiveSessions(android.content.ComponentName);
- method public void removeActiveSessionsListener(android.media.session.MediaSessionManager.SessionListener);
+ method public void removeOnActiveSessionsChangedListener(android.media.session.MediaSessionManager.OnActiveSessionsChangedListener);
}
- public static abstract class MediaSessionManager.SessionListener {
- ctor public MediaSessionManager.SessionListener(android.content.Context);
+ public static abstract interface MediaSessionManager.OnActiveSessionsChangedListener {
method public abstract void onActiveSessionsChanged(java.util.List<android.media.session.MediaController>);
}
@@ -16766,9 +16776,9 @@
field public static final long ACTION_REWIND = 8L; // 0x8L
field public static final long ACTION_SEEK_TO = 256L; // 0x100L
field public static final long ACTION_SET_RATING = 128L; // 0x80L
+ field public static final long ACTION_SKIP_TO_ITEM = 4096L; // 0x1000L
field public static final long ACTION_SKIP_TO_NEXT = 32L; // 0x20L
field public static final long ACTION_SKIP_TO_PREVIOUS = 16L; // 0x10L
- field public static final long ACTION_SKIP_TO_TRACK = 4096L; // 0x1000L
field public static final long ACTION_STOP = 1L; // 0x1L
field public static final android.os.Parcelable.Creator CREATOR;
field public static final long PLAYBACK_POSITION_UNKNOWN = -1L; // 0xffffffffffffffffL
@@ -16792,7 +16802,7 @@
method public android.media.session.PlaybackState.Builder addCustomAction(android.media.session.PlaybackState.CustomAction);
method public android.media.session.PlaybackState build();
method public android.media.session.PlaybackState.Builder setActions(long);
- method public android.media.session.PlaybackState.Builder setActiveTrack(long);
+ method public android.media.session.PlaybackState.Builder setActiveItem(long);
method public android.media.session.PlaybackState.Builder setBufferPosition(long);
method public android.media.session.PlaybackState.Builder setErrorMessage(java.lang.CharSequence);
method public android.media.session.PlaybackState.Builder setState(int, long, float, long);
@@ -29626,6 +29636,7 @@
method public int hasCarrierPrivileges();
method public boolean hasIccCard();
method public boolean iccCloseLogicalChannel(int);
+ method public byte[] iccExchangeSimIO(int, int, int, int, int, java.lang.String);
method public android.telephony.IccOpenLogicalChannelResponse iccOpenLogicalChannel(java.lang.String);
method public java.lang.String iccTransmitApduBasicChannel(int, int, int, int, int, java.lang.String);
method public java.lang.String iccTransmitApduLogicalChannel(int, int, int, int, int, int, java.lang.String);
@@ -32227,6 +32238,8 @@
method public void captureEndValues(android.transition.TransitionValues);
method public void captureStartValues(android.transition.TransitionValues);
method public int getOrdering();
+ method public android.transition.Transition getTransitionAt(int);
+ method public int getTransitionCount();
method public android.transition.TransitionSet removeTransition(android.transition.Transition);
method public android.transition.TransitionSet setOrdering(int);
field public static final int ORDERING_SEQUENTIAL = 1; // 0x1
diff --git a/cmds/appops/Android.mk b/cmds/appops/Android.mk
new file mode 100644
index 0000000..1e15204
--- /dev/null
+++ b/cmds/appops/Android.mk
@@ -0,0 +1,16 @@
+# Copyright 2014 The Android Open Source Project
+
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+LOCAL_SRC_FILES := $(call all-subdir-java-files)
+LOCAL_MODULE := appops
+include $(BUILD_JAVA_LIBRARY)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := appops
+LOCAL_SRC_FILES := appops
+LOCAL_MODULE_CLASS := EXECUTABLES
+LOCAL_MODULE_TAGS := optional
+include $(BUILD_PREBUILT)
+
diff --git a/cmds/appops/MODULE_LICENSE_APACHE2 b/cmds/appops/MODULE_LICENSE_APACHE2
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/cmds/appops/MODULE_LICENSE_APACHE2
diff --git a/cmds/appops/NOTICE b/cmds/appops/NOTICE
new file mode 100644
index 0000000..06a9081
--- /dev/null
+++ b/cmds/appops/NOTICE
@@ -0,0 +1,190 @@
+
+ Copyright (c) 2005-2014, The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+
+ 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.
+
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
diff --git a/cmds/appops/appops b/cmds/appops/appops
new file mode 100755
index 0000000..407e551
--- /dev/null
+++ b/cmds/appops/appops
@@ -0,0 +1,5 @@
+# Script to start "appwidget" on the device, which has a very rudimentary shell.
+base=/system
+export CLASSPATH=$base/framework/appops.jar
+exec app_process $base/bin com.android.commands.appops.AppOpsCommand "$@"
+
diff --git a/cmds/appops/src/com/android/commands/appops/AppOpsCommand.java b/cmds/appops/src/com/android/commands/appops/AppOpsCommand.java
new file mode 100644
index 0000000..c414f58
--- /dev/null
+++ b/cmds/appops/src/com/android/commands/appops/AppOpsCommand.java
@@ -0,0 +1,137 @@
+/*
+** Copyright 2014, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+
+package com.android.commands.appops;
+
+import android.app.ActivityManager;
+import android.app.ActivityThread;
+import android.app.AppOpsManager;
+import android.content.Context;
+import android.content.pm.IPackageManager;
+import android.os.ServiceManager;
+import android.os.UserHandle;
+
+import com.android.internal.app.IAppOpsService;
+import com.android.internal.os.BaseCommand;
+
+import java.io.PrintStream;
+
+/**
+ * This class is a command line utility for manipulating AppOps permissions.
+ */
+public class AppOpsCommand extends BaseCommand {
+
+ public static void main(String[] args) {
+ new AppOpsCommand().run(args);
+ }
+
+ @Override
+ public void onShowUsage(PrintStream out) {
+ out.println("usage: adb shell appops set <PACKAGE> <OP> "
+ + "<allow|ignore|deny|default> [--user <USER_ID>]\n"
+ + " <PACKAGE> an Android package name.\n"
+ + " <OP> an AppOps operation.\n"
+ + " <USER_ID> the user id under which the package is installed. If --user is not\n"
+ + " specified, the current user is assumed.\n");
+ }
+
+ private static final String COMMAND_SET = "set";
+
+ @Override
+ public void onRun() throws Exception {
+ String command = nextArgRequired();
+ switch (command) {
+ case COMMAND_SET:
+ runSet();
+ break;
+
+ default:
+ throw new IllegalArgumentException("Unknown command '" + command + "'.");
+ }
+ }
+
+ private static final String ARGUMENT_USER = "--user";
+
+ // Modes
+ private static final String MODE_ALLOW = "allow";
+ private static final String MODE_DENY = "deny";
+ private static final String MODE_IGNORE = "ignore";
+ private static final String MODE_DEFAULT = "default";
+
+ private void runSet() throws Exception {
+ String packageName = null;
+ String op = null;
+ String mode = null;
+ int userId = UserHandle.USER_CURRENT;
+ for (String argument; (argument = nextArg()) != null;) {
+ if (ARGUMENT_USER.equals(argument)) {
+ userId = Integer.parseInt(nextArgRequired());
+ } else {
+ if (packageName == null) {
+ packageName = argument;
+ } else if (op == null) {
+ op = argument;
+ } else if (mode == null) {
+ mode = argument;
+ } else {
+ throw new IllegalArgumentException("Unsupported argument: " + argument);
+ }
+ }
+ }
+
+ if (packageName == null) {
+ throw new IllegalArgumentException("Package name not specified.");
+ } else if (op == null) {
+ throw new IllegalArgumentException("Operation not specified.");
+ } else if (mode == null) {
+ throw new IllegalArgumentException("Mode not specified.");
+ }
+
+ final int opInt = AppOpsManager.strOpToOp(op);
+ final int modeInt;
+ switch (mode) {
+ case MODE_ALLOW:
+ modeInt = AppOpsManager.MODE_ALLOWED;
+ break;
+ case MODE_DENY:
+ modeInt = AppOpsManager.MODE_ERRORED;
+ break;
+ case MODE_IGNORE:
+ modeInt = AppOpsManager.MODE_IGNORED;
+ break;
+ case MODE_DEFAULT:
+ modeInt = AppOpsManager.MODE_DEFAULT;
+ break;
+ default:
+ throw new IllegalArgumentException("Mode is invalid.");
+ }
+
+ // Parsing complete, let's execute the command.
+
+ if (userId == UserHandle.USER_CURRENT) {
+ userId = ActivityManager.getCurrentUser();
+ }
+
+ final IPackageManager pm = ActivityThread.getPackageManager();
+ final IAppOpsService appOpsService = IAppOpsService.Stub.asInterface(
+ ServiceManager.getService(Context.APP_OPS_SERVICE));
+ final int uid = pm.getPackageUid(packageName, userId);
+ if (uid < 0) {
+ throw new Exception("No UID for " + packageName + " for user " + userId);
+ }
+ appOpsService.setMode(opInt, uid, packageName, modeInt);
+ }
+}
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index d9ea671..2136209 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -3494,6 +3494,20 @@
synchronized (mResourcesManager) {
mCoreSettings = coreSettings;
}
+ onCoreSettingsChange();
+ }
+
+ private void onCoreSettingsChange() {
+ boolean debugViewAttributes =
+ mCoreSettings.getInt(Settings.Global.DEBUG_VIEW_ATTRIBUTES, 0) != 0;
+ if (debugViewAttributes != View.mDebugViewAttributes) {
+ View.mDebugViewAttributes = debugViewAttributes;
+
+ // request all activities to relaunch for the changes to take place
+ for (Map.Entry<IBinder, ActivityClientRecord> entry : mActivities.entrySet()) {
+ requestRelaunchActivity(entry.getKey(), null, null, 0, false, null, false);
+ }
+ }
}
private void handleUpdatePackageCompatibilityInfo(UpdateCompatibilityData data) {
@@ -4324,6 +4338,9 @@
final boolean is24Hr = "24".equals(mCoreSettings.getString(Settings.System.TIME_12_24));
DateFormat.set24HourTimePref(is24Hr);
+ View.mDebugViewAttributes =
+ mCoreSettings.getInt(Settings.Global.DEBUG_VIEW_ATTRIBUTES, 0) != 0;
+
/**
* For system applications on userdebug/eng builds, log stack
* traces of disk and network access to dropbox for analysis.
diff --git a/core/java/android/app/AppOpsManager.java b/core/java/android/app/AppOpsManager.java
index a6b3608..0d2ad08 100644
--- a/core/java/android/app/AppOpsManager.java
+++ b/core/java/android/app/AppOpsManager.java
@@ -1046,7 +1046,10 @@
return packageName + " from uid " + uid + " not allowed to perform " + sOpNames[op];
}
- private int strOpToOp(String op) {
+ /**
+ * {@hide}
+ */
+ public static int strOpToOp(String op) {
Integer val = sOpStrToOp.get(op);
if (val == null) {
throw new IllegalArgumentException("Unknown operation string: " + op);
diff --git a/core/java/android/content/ContentResolver.java b/core/java/android/content/ContentResolver.java
index 0ca800f..b13792b 100644
--- a/core/java/android/content/ContentResolver.java
+++ b/core/java/android/content/ContentResolver.java
@@ -1612,7 +1612,7 @@
* @see #requestSync(android.accounts.Account, String, android.os.Bundle)
*/
public void notifyChange(Uri uri, ContentObserver observer, boolean syncToNetwork) {
- notifyChange(uri, observer, syncToNetwork, UserHandle.getCallingUserId());
+ notifyChange(uri, observer, syncToNetwork, UserHandle.myUserId());
}
/**
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index 5f046c5..a13a928 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -45,6 +45,7 @@
import android.util.AttributeSet;
import android.view.DisplayAdjustments;
import android.view.Display;
+import android.view.ViewDebug;
import android.view.WindowManager;
import java.io.File;
@@ -420,6 +421,7 @@
/**
* Return the Theme object associated with this Context.
*/
+ @ViewDebug.ExportedProperty(deepExport = true)
public abstract Resources.Theme getTheme();
/**
diff --git a/core/java/android/content/pm/LauncherApps.java b/core/java/android/content/pm/LauncherApps.java
index 268919c..f9370b3 100644
--- a/core/java/android/content/pm/LauncherApps.java
+++ b/core/java/android/content/pm/LauncherApps.java
@@ -64,7 +64,7 @@
/**
* Callbacks for package changes to this and related managed profiles.
*/
- public static abstract class OnAppsChangedCallback {
+ public static abstract class Callback {
/**
* Indicates that a package was removed from the specified profile.
*
@@ -207,17 +207,17 @@
}
/**
- * Starts an activity in the specified profile.
+ * Starts a Main activity in the specified profile.
*
* @param component The ComponentName of the activity to launch
* @param user The UserHandle of the profile
* @param sourceBounds The Rect containing the source bounds of the clicked icon
* @param opts Options to pass to startActivity
*/
- public void startActivityForProfile(ComponentName component, UserHandle user, Rect sourceBounds,
+ public void startMainActivity(ComponentName component, UserHandle user, Rect sourceBounds,
Bundle opts) {
if (DEBUG) {
- Log.i(TAG, "StartActivityForProfile " + component + " " + user.getIdentifier());
+ Log.i(TAG, "StartMainActivity " + component + " " + user.getIdentifier());
}
try {
mService.startActivityAsUser(component, sourceBounds, opts, user);
@@ -235,7 +235,7 @@
* @param sourceBounds The Rect containing the source bounds of the clicked icon
* @param opts Options to pass to startActivity
*/
- public void showAppDetailsForProfile(ComponentName component, UserHandle user,
+ public void startAppDetailsActivity(ComponentName component, UserHandle user,
Rect sourceBounds, Bundle opts) {
try {
mService.showAppDetailsAsUser(component, sourceBounds, opts, user);
@@ -252,7 +252,7 @@
*
* @return true if the package exists and is enabled.
*/
- public boolean isPackageEnabledForProfile(String packageName, UserHandle user) {
+ public boolean isPackageEnabled(String packageName, UserHandle user) {
try {
return mService.isPackageEnabled(packageName, user);
} catch (RemoteException re) {
@@ -268,7 +268,7 @@
*
* @return true if the activity exists and is enabled.
*/
- public boolean isActivityEnabledForProfile(ComponentName component, UserHandle user) {
+ public boolean isActivityEnabled(ComponentName component, UserHandle user) {
try {
return mService.isActivityEnabled(component, user);
} catch (RemoteException re) {
@@ -282,8 +282,8 @@
*
* @param callback The callback to add.
*/
- public void addOnAppsChangedCallback(OnAppsChangedCallback callback) {
- addOnAppsChangedCallback(callback, null);
+ public void addCallback(Callback callback) {
+ addCallback(callback, null);
}
/**
@@ -292,7 +292,7 @@
* @param callback The callback to add.
* @param handler that should be used to post callbacks on, may be null.
*/
- public void addOnAppsChangedCallback(OnAppsChangedCallback callback, Handler handler) {
+ public void addCallback(Callback callback, Handler handler) {
synchronized (this) {
if (callback != null && !mCallbacks.contains(callback)) {
boolean addedFirstCallback = mCallbacks.size() == 0;
@@ -311,9 +311,9 @@
* Removes a callback that was previously added.
*
* @param callback The callback to remove.
- * @see #addOnAppsChangedListener(OnAppsChangedCallback)
+ * @see #addCallback(Callback)
*/
- public void removeOnAppsChangedCallback(OnAppsChangedCallback callback) {
+ public void removeCallback(Callback callback) {
synchronized (this) {
removeCallbackLocked(callback);
if (mCallbacks.size() == 0) {
@@ -325,7 +325,7 @@
}
}
- private void removeCallbackLocked(OnAppsChangedCallback callback) {
+ private void removeCallbackLocked(Callback callback) {
if (callback == null) {
throw new IllegalArgumentException("Callback cannot be null");
}
@@ -338,7 +338,7 @@
}
}
- private void addCallbackLocked(OnAppsChangedCallback callback, Handler handler) {
+ private void addCallbackLocked(Callback callback, Handler handler) {
// Remove if already present.
removeCallbackLocked(callback);
if (handler == null) {
@@ -421,7 +421,7 @@
private static final int MSG_AVAILABLE = 4;
private static final int MSG_UNAVAILABLE = 5;
- private OnAppsChangedCallback mCallback;
+ private LauncherApps.Callback mCallback;
private static class CallbackInfo {
String[] packageNames;
@@ -430,7 +430,7 @@
UserHandle user;
}
- public CallbackMessageHandler(Looper looper, OnAppsChangedCallback callback) {
+ public CallbackMessageHandler(Looper looper, LauncherApps.Callback callback) {
super(looper, null, true);
mCallback = callback;
}
@@ -499,4 +499,45 @@
obtainMessage(MSG_UNAVAILABLE, info).sendToTarget();
}
}
+
+ /** Remove after unbundled apps have migrated STOP SHIP */
+ public static abstract class OnAppsChangedCallback extends Callback {
+ }
+
+ /** Remove after unbundled apps have migrated STOP SHIP */
+ public void addOnAppsChangedCallback(OnAppsChangedCallback callback) {
+ addCallback(callback, null);
+ }
+
+ /** Remove after unbundled apps have migrated STOP SHIP */
+ public void addOnAppsChangedCallback(OnAppsChangedCallback callback, Handler handler) {
+ addCallback(callback, handler);
+ }
+
+ /** Remove after unbundled apps have migrated STOP SHIP */
+ public void removeOnAppsChangedCallback(OnAppsChangedCallback callback) {
+ removeCallback(callback);
+ }
+
+ /** Remove after unbundled apps have migrated STOP SHIP */
+ public void startActivityForProfile(ComponentName component, UserHandle user, Rect sourceBounds,
+ Bundle opts) {
+ startMainActivity(component, user, sourceBounds, opts);
+ }
+
+ /** Remove after unbundled apps have migrated STOP SHIP */
+ public void showAppDetailsForProfile(ComponentName component, UserHandle user,
+ Rect sourceBounds, Bundle opts) {
+ startAppDetailsActivity(component, user, sourceBounds, opts);
+ }
+
+ /** Remove after unbundled apps have migrated STOP SHIP */
+ public boolean isPackageEnabledForProfile(String packageName, UserHandle user) {
+ return isPackageEnabled(packageName, user);
+ }
+
+ /** Remove after unbundled apps have migrated STOP SHIP */
+ public boolean isActivityEnabledForProfile(ComponentName component, UserHandle user) {
+ return isActivityEnabled(component, user);
+ }
}
diff --git a/core/java/android/content/res/Resources.java b/core/java/android/content/res/Resources.java
index fff21aa..31813c10 100644
--- a/core/java/android/content/res/Resources.java
+++ b/core/java/android/content/res/Resources.java
@@ -16,6 +16,7 @@
package android.content.res;
+import android.view.ViewDebug;
import com.android.internal.util.XmlUtils;
import org.xmlpull.v1.XmlPullParser;
@@ -1638,12 +1639,41 @@
/*package*/ String getKey() {
return mKey;
}
+
+ private String getResourceNameFromHexString(String hexString) {
+ return getResourceName(Integer.parseInt(hexString, 16));
+ }
+
+ /**
+ * Parses {@link #mKey} and returns a String array that holds pairs of adjacent Theme data:
+ * resource name followed by whether or not it was forced, as specified by
+ * {@link #applyStyle(int, boolean)}.
+ *
+ * @hide
+ */
+ @ViewDebug.ExportedProperty(category = "theme", hasAdjacentMapping = true)
+ public String[] getTheme() {
+ String[] themeData = mKey.split(" ");
+ String[] themes = new String[themeData.length * 2];
+ String theme;
+ boolean forced;
+
+ for (int i = 0, j = themeData.length - 1; i < themes.length; i += 2, --j) {
+ theme = themeData[j];
+ forced = theme.endsWith("!");
+ themes[i] = forced ?
+ getResourceNameFromHexString(theme.substring(0, theme.length() - 1)) :
+ getResourceNameFromHexString(theme);
+ themes[i + 1] = forced ? "forced" : "not forced";
+ }
+ return themes;
+ }
}
/**
* Generate a new Theme object for this set of Resources. It initially
* starts out empty.
- *
+ *
* @return Theme The newly created Theme container.
*/
public final Theme newTheme() {
@@ -1653,7 +1683,7 @@
/**
* Retrieve a set of basic attribute values from an AttributeSet, not
* performing styling of them using a theme and/or style resources.
- *
+ *
* @param set The current attribute values to retrieve.
* @param attrs The specific attributes to be retrieved.
* @return Returns a TypedArray holding an array of the attribute values.
diff --git a/core/java/android/hardware/camera2/legacy/LegacyMetadataMapper.java b/core/java/android/hardware/camera2/legacy/LegacyMetadataMapper.java
index fbe26e5..ee0ca9c 100644
--- a/core/java/android/hardware/camera2/legacy/LegacyMetadataMapper.java
+++ b/core/java/android/hardware/camera2/legacy/LegacyMetadataMapper.java
@@ -1207,6 +1207,9 @@
m.set(CaptureRequest.CONTROL_AE_TARGET_FPS_RANGE, bestRange);
}
+ // control.sceneMode -- DISABLED is always available
+ m.set(CaptureRequest.CONTROL_SCENE_MODE, CONTROL_SCENE_MODE_DISABLED);
+
/*
* statistics.*
*/
diff --git a/core/java/android/hardware/camera2/params/StreamConfigurationMap.java b/core/java/android/hardware/camera2/params/StreamConfigurationMap.java
index 2e6b9ae..c0b7967 100644
--- a/core/java/android/hardware/camera2/params/StreamConfigurationMap.java
+++ b/core/java/android/hardware/camera2/params/StreamConfigurationMap.java
@@ -339,6 +339,11 @@
* @see #isOutputSupportedFor(Class)
*/
public <T> Size[] getOutputSizes(Class<T> klass) {
+ // Image reader is "supported", but never for implementation-defined formats; return empty
+ if (android.media.ImageReader.class.isAssignableFrom(klass)) {
+ return new Size[0];
+ }
+
if (isOutputSupportedFor(klass) == false) {
return null;
}
diff --git a/core/java/android/hardware/hdmi/HdmiDeviceInfo.java b/core/java/android/hardware/hdmi/HdmiDeviceInfo.java
index 97da3a2..d8da80e 100644
--- a/core/java/android/hardware/hdmi/HdmiDeviceInfo.java
+++ b/core/java/android/hardware/hdmi/HdmiDeviceInfo.java
@@ -230,7 +230,7 @@
mDeviceType = DEVICE_RESERVED;
mVendorId = 0;
mDevicePowerStatus = HdmiControlManager.POWER_STATUS_UNKNOWN;
- mDisplayName = "MHL";
+ mDisplayName = "Mobile";
mDeviceId = adopterId;
mAdopterId = deviceId;
diff --git a/core/java/android/net/DhcpResults.java b/core/java/android/net/DhcpResults.java
index 49a307e..71df60a 100644
--- a/core/java/android/net/DhcpResults.java
+++ b/core/java/android/net/DhcpResults.java
@@ -16,13 +16,15 @@
package android.net;
+import android.net.NetworkUtils;
import android.os.Parcelable;
import android.os.Parcel;
import android.text.TextUtils;
import android.util.Log;
import java.net.InetAddress;
-import java.net.UnknownHostException;
+import java.net.Inet4Address;
+import java.util.Objects;
/**
* A simple object for retrieving the results of a DHCP request.
@@ -30,38 +32,34 @@
* TODO - remove when DhcpInfo is deprecated. Move the remaining api to LinkProperties.
* @hide
*/
-public class DhcpResults implements Parcelable {
+public class DhcpResults extends StaticIpConfiguration {
private static final String TAG = "DhcpResults";
- public final LinkProperties linkProperties;
-
public InetAddress serverAddress;
- /**
- * Vendor specific information (from RFC 2132).
- */
+ /** Vendor specific information (from RFC 2132). */
public String vendorInfo;
public int leaseDuration;
public DhcpResults() {
- linkProperties = new LinkProperties();
+ super();
+ }
+
+ public DhcpResults(StaticIpConfiguration source) {
+ super(source);
}
/** copy constructor */
public DhcpResults(DhcpResults source) {
- if (source != null) {
- linkProperties = new LinkProperties(source.linkProperties);
- serverAddress = source.serverAddress;
- leaseDuration = source.leaseDuration;
- vendorInfo = source.vendorInfo;
- } else {
- linkProperties = new LinkProperties();
- }
- }
+ super(source);
- public DhcpResults(LinkProperties lp) {
- linkProperties = new LinkProperties(lp);
+ if (source != null) {
+ // All these are immutable, so no need to make copies.
+ serverAddress = source.serverAddress;
+ vendorInfo = source.vendorInfo;
+ leaseDuration = source.leaseDuration;
+ }
}
/**
@@ -70,14 +68,10 @@
* being empty.
*/
public void updateFromDhcpRequest(DhcpResults orig) {
- if (orig == null || orig.linkProperties == null) return;
- if (linkProperties.getRoutes().size() == 0) {
- for (RouteInfo r : orig.linkProperties.getRoutes()) linkProperties.addRoute(r);
- }
- if (linkProperties.getDnsServers().size() == 0) {
- for (InetAddress d : orig.linkProperties.getDnsServers()) {
- linkProperties.addDnsServer(d);
- }
+ if (orig == null) return;
+ if (gateway == null) gateway = orig.gateway;
+ if (dnsServers.size() == 0) {
+ dnsServers.addAll(orig.dnsServers);
}
}
@@ -94,15 +88,14 @@
}
public void clear() {
- linkProperties.clear();
- serverAddress = null;
+ super.clear();
vendorInfo = null;
leaseDuration = 0;
}
@Override
public String toString() {
- StringBuffer str = new StringBuffer(linkProperties.toString());
+ StringBuffer str = new StringBuffer(super.toString());
str.append(" DHCP server ").append(serverAddress);
str.append(" Vendor info ").append(vendorInfo);
@@ -119,58 +112,19 @@
DhcpResults target = (DhcpResults)obj;
- if (linkProperties == null) {
- if (target.linkProperties != null) return false;
- } else if (!linkProperties.equals(target.linkProperties)) return false;
- if (serverAddress == null) {
- if (target.serverAddress != null) return false;
- } else if (!serverAddress.equals(target.serverAddress)) return false;
- if (vendorInfo == null) {
- if (target.vendorInfo != null) return false;
- } else if (!vendorInfo.equals(target.vendorInfo)) return false;
- if (leaseDuration != target.leaseDuration) return false;
-
- return true;
- }
-
- /** Implement the Parcelable interface */
- public int describeContents() {
- return 0;
- }
-
- /** Implement the Parcelable interface */
- public void writeToParcel(Parcel dest, int flags) {
- linkProperties.writeToParcel(dest, flags);
-
- dest.writeInt(leaseDuration);
-
- if (serverAddress != null) {
- dest.writeByte((byte)1);
- dest.writeByteArray(serverAddress.getAddress());
- } else {
- dest.writeByte((byte)0);
- }
-
- dest.writeString(vendorInfo);
+ return super.equals((StaticIpConfiguration) obj) &&
+ Objects.equals(serverAddress, target.serverAddress) &&
+ Objects.equals(vendorInfo, target.vendorInfo) &&
+ leaseDuration == target.leaseDuration;
}
/** Implement the Parcelable interface */
public static final Creator<DhcpResults> CREATOR =
new Creator<DhcpResults>() {
public DhcpResults createFromParcel(Parcel in) {
- DhcpResults prop = new DhcpResults((LinkProperties)in.readParcelable(null));
-
- prop.leaseDuration = in.readInt();
-
- if (in.readByte() == 1) {
- try {
- prop.serverAddress = InetAddress.getByAddress(in.createByteArray());
- } catch (UnknownHostException e) {}
- }
-
- prop.vendorInfo = in.readString();
-
- return prop;
+ DhcpResults dhcpResults = new DhcpResults();
+ readFromParcel(dhcpResults, in);
+ return dhcpResults;
}
public DhcpResults[] newArray(int size) {
@@ -178,33 +132,39 @@
}
};
- // Utils for jni population - false on success
- public void setInterfaceName(String interfaceName) {
- linkProperties.setInterfaceName(interfaceName);
+ /** Implement the Parcelable interface */
+ public void writeToParcel(Parcel dest, int flags) {
+ super.writeToParcel(dest, flags);
+ dest.writeInt(leaseDuration);
+ NetworkUtils.parcelInetAddress(dest, serverAddress, flags);
+ dest.writeString(vendorInfo);
}
- public boolean addLinkAddress(String addrString, int prefixLength) {
- InetAddress addr;
+ private static void readFromParcel(DhcpResults dhcpResults, Parcel in) {
+ StaticIpConfiguration.readFromParcel(dhcpResults, in);
+ dhcpResults.leaseDuration = in.readInt();
+ dhcpResults.serverAddress = NetworkUtils.unparcelInetAddress(in);
+ dhcpResults.vendorInfo = in.readString();
+ }
+
+ // Utils for jni population - false on success
+ // Not part of the superclass because they're only used by the JNI iterface to the DHCP daemon.
+ public boolean setIpAddress(String addrString, int prefixLength) {
try {
- addr = NetworkUtils.numericToInetAddress(addrString);
- } catch (IllegalArgumentException e) {
- Log.e(TAG, "addLinkAddress failed with addrString " + addrString);
+ Inet4Address addr = (Inet4Address) NetworkUtils.numericToInetAddress(addrString);
+ ipAddress = new LinkAddress(addr, prefixLength);
+ } catch (IllegalArgumentException|ClassCastException e) {
+ Log.e(TAG, "setIpAddress failed with addrString " + addrString + "/" + prefixLength);
return true;
}
-
- LinkAddress linkAddress = new LinkAddress(addr, prefixLength);
- linkProperties.addLinkAddress(linkAddress);
-
- RouteInfo routeInfo = new RouteInfo(linkAddress);
- linkProperties.addRoute(routeInfo);
return false;
}
- public boolean addGateway(String addrString) {
+ public boolean setGateway(String addrString) {
try {
- linkProperties.addRoute(new RouteInfo(NetworkUtils.numericToInetAddress(addrString)));
+ gateway = NetworkUtils.numericToInetAddress(addrString);
} catch (IllegalArgumentException e) {
- Log.e(TAG, "addGateway failed with addrString " + addrString);
+ Log.e(TAG, "setGateway failed with addrString " + addrString);
return true;
}
return false;
@@ -213,7 +173,7 @@
public boolean addDns(String addrString) {
if (TextUtils.isEmpty(addrString) == false) {
try {
- linkProperties.addDnsServer(NetworkUtils.numericToInetAddress(addrString));
+ dnsServers.add(NetworkUtils.numericToInetAddress(addrString));
} catch (IllegalArgumentException e) {
Log.e(TAG, "addDns failed with addrString " + addrString);
return true;
@@ -241,6 +201,6 @@
}
public void setDomains(String domains) {
- linkProperties.setDomains(domains);
+ domains = domains;
}
}
diff --git a/core/java/android/net/EthernetManager.java b/core/java/android/net/EthernetManager.java
index 608ca28..d965f27 100644
--- a/core/java/android/net/EthernetManager.java
+++ b/core/java/android/net/EthernetManager.java
@@ -21,7 +21,6 @@
import android.net.IpConfiguration;
import android.net.IpConfiguration.IpAssignment;
import android.net.IpConfiguration.ProxySettings;
-import android.net.LinkProperties;
import android.os.RemoteException;
/**
@@ -52,16 +51,12 @@
*/
public IpConfiguration getConfiguration() {
if (mService == null) {
- return new IpConfiguration(IpAssignment.UNASSIGNED,
- ProxySettings.UNASSIGNED,
- new LinkProperties());
+ return new IpConfiguration();
}
try {
return mService.getConfiguration();
} catch (RemoteException e) {
- return new IpConfiguration(IpAssignment.UNASSIGNED,
- ProxySettings.UNASSIGNED,
- new LinkProperties());
+ return new IpConfiguration();
}
}
diff --git a/core/java/android/net/IpConfiguration.java b/core/java/android/net/IpConfiguration.java
index 4730bab..fe69f296 100644
--- a/core/java/android/net/IpConfiguration.java
+++ b/core/java/android/net/IpConfiguration.java
@@ -16,7 +16,7 @@
package android.net;
-import android.net.LinkProperties;
+import android.net.StaticIpConfiguration;
import android.os.Parcel;
import android.os.Parcelable;
@@ -31,7 +31,7 @@
public enum IpAssignment {
/* Use statically configured IP settings. Configuration can be accessed
- * with linkProperties */
+ * with staticIpConfiguration */
STATIC,
/* Use dynamically configured IP settigns */
DHCP,
@@ -42,12 +42,14 @@
public IpAssignment ipAssignment;
+ public StaticIpConfiguration staticIpConfiguration;
+
public enum ProxySettings {
/* No proxy is to be used. Any existing proxy settings
* should be cleared. */
NONE,
/* Use statically configured proxy. Configuration can be accessed
- * with linkProperties */
+ * with httpProxy. */
STATIC,
/* no proxy details are assigned, this is used to indicate
* that any existing proxy settings should be retained */
@@ -59,30 +61,69 @@
public ProxySettings proxySettings;
- public LinkProperties linkProperties;
+ public ProxyInfo httpProxy;
- public IpConfiguration(IpConfiguration source) {
- if (source != null) {
- ipAssignment = source.ipAssignment;
- proxySettings = source.proxySettings;
- linkProperties = new LinkProperties(source.linkProperties);
- } else {
- ipAssignment = IpAssignment.UNASSIGNED;
- proxySettings = ProxySettings.UNASSIGNED;
- linkProperties = new LinkProperties();
- }
+ private void init(IpAssignment ipAssignment,
+ ProxySettings proxySettings,
+ StaticIpConfiguration staticIpConfiguration,
+ ProxyInfo httpProxy) {
+ this.ipAssignment = ipAssignment;
+ this.proxySettings = proxySettings;
+ this.staticIpConfiguration = (staticIpConfiguration == null) ?
+ null : new StaticIpConfiguration(staticIpConfiguration);
+ this.httpProxy = (httpProxy == null) ?
+ null : new ProxyInfo(httpProxy);
}
public IpConfiguration() {
- this(null);
+ init(IpAssignment.UNASSIGNED, ProxySettings.UNASSIGNED, null, null);
}
public IpConfiguration(IpAssignment ipAssignment,
ProxySettings proxySettings,
- LinkProperties linkProperties) {
+ StaticIpConfiguration staticIpConfiguration,
+ ProxyInfo httpProxy) {
+ init(ipAssignment, proxySettings, staticIpConfiguration, httpProxy);
+ }
+
+ public IpConfiguration(IpConfiguration source) {
+ this();
+ if (source != null) {
+ init(source.ipAssignment, source.proxySettings,
+ source.staticIpConfiguration, source.httpProxy);
+ }
+ }
+
+ public IpAssignment getIpAssignment() {
+ return ipAssignment;
+ }
+
+ public void setIpAssignment(IpAssignment ipAssignment) {
this.ipAssignment = ipAssignment;
+ }
+
+ public StaticIpConfiguration getStaticIpConfiguration() {
+ return staticIpConfiguration;
+ }
+
+ public void setStaticIpConfiguration(StaticIpConfiguration staticIpConfiguration) {
+ this.staticIpConfiguration = staticIpConfiguration;
+ }
+
+ public ProxySettings getProxySettings() {
+ return proxySettings;
+ }
+
+ public void setProxySettings(ProxySettings proxySettings) {
this.proxySettings = proxySettings;
- this.linkProperties = new LinkProperties(linkProperties);
+ }
+
+ public ProxyInfo getHttpProxy() {
+ return httpProxy;
+ }
+
+ public void setHttpProxy(ProxyInfo httpProxy) {
+ this.httpProxy = httpProxy;
}
@Override
@@ -90,10 +131,16 @@
StringBuilder sbuf = new StringBuilder();
sbuf.append("IP assignment: " + ipAssignment.toString());
sbuf.append("\n");
+ if (staticIpConfiguration != null) {
+ sbuf.append("Static configuration: " + staticIpConfiguration.toString());
+ sbuf.append("\n");
+ }
sbuf.append("Proxy settings: " + proxySettings.toString());
sbuf.append("\n");
- sbuf.append(linkProperties.toString());
- sbuf.append("\n");
+ if (httpProxy != null) {
+ sbuf.append("HTTP proxy: " + httpProxy.toString());
+ sbuf.append("\n");
+ }
return sbuf.toString();
}
@@ -111,14 +158,16 @@
IpConfiguration other = (IpConfiguration) o;
return this.ipAssignment == other.ipAssignment &&
this.proxySettings == other.proxySettings &&
- Objects.equals(this.linkProperties, other.linkProperties);
+ Objects.equals(this.staticIpConfiguration, other.staticIpConfiguration) &&
+ Objects.equals(this.httpProxy, other.httpProxy);
}
@Override
public int hashCode() {
- return 13 + (linkProperties != null ? linkProperties.hashCode() : 0) +
+ return 13 + (staticIpConfiguration != null ? staticIpConfiguration.hashCode() : 0) +
17 * ipAssignment.ordinal() +
- 47 * proxySettings.ordinal();
+ 47 * proxySettings.ordinal() +
+ 83 * httpProxy.hashCode();
}
/** Implement the Parcelable interface */
@@ -130,7 +179,8 @@
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(ipAssignment.name());
dest.writeString(proxySettings.name());
- dest.writeParcelable(linkProperties, flags);
+ dest.writeParcelable(staticIpConfiguration, flags);
+ dest.writeParcelable(httpProxy, flags);
}
/** Implement the Parcelable interface */
@@ -140,7 +190,8 @@
IpConfiguration config = new IpConfiguration();
config.ipAssignment = IpAssignment.valueOf(in.readString());
config.proxySettings = ProxySettings.valueOf(in.readString());
- config.linkProperties = in.readParcelable(null);
+ config.staticIpConfiguration = in.readParcelable(null);
+ config.httpProxy = in.readParcelable(null);
return config;
}
diff --git a/core/java/android/net/NetworkUtils.java b/core/java/android/net/NetworkUtils.java
index 663aa15..54d8676 100644
--- a/core/java/android/net/NetworkUtils.java
+++ b/core/java/android/net/NetworkUtils.java
@@ -23,6 +23,7 @@
import java.util.Collection;
import java.util.Locale;
+import android.os.Parcel;
import android.util.Log;
import android.util.Pair;
@@ -203,6 +204,32 @@
}
/**
+ * Writes an InetAddress to a parcel. The address may be null. This is likely faster than
+ * calling writeSerializable.
+ */
+ protected static void parcelInetAddress(Parcel parcel, InetAddress address, int flags) {
+ byte[] addressArray = (address != null) ? address.getAddress() : null;
+ parcel.writeByteArray(addressArray);
+ }
+
+ /**
+ * Reads an InetAddress from a parcel. Returns null if the address that was written was null
+ * or if the data is invalid.
+ */
+ protected static InetAddress unparcelInetAddress(Parcel in) {
+ byte[] addressArray = in.createByteArray();
+ if (addressArray == null) {
+ return null;
+ }
+ try {
+ return InetAddress.getByAddress(addressArray);
+ } catch (UnknownHostException e) {
+ return null;
+ }
+ }
+
+
+ /**
* Masks a raw IP address byte array with the specified prefix length.
*/
public static void maskRawAddress(byte[] array, int prefixLength) {
diff --git a/core/java/android/net/StaticIpConfiguration.java b/core/java/android/net/StaticIpConfiguration.java
new file mode 100644
index 0000000..5a273cf
--- /dev/null
+++ b/core/java/android/net/StaticIpConfiguration.java
@@ -0,0 +1,194 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net;
+
+import android.net.LinkAddress;
+import android.os.Parcelable;
+import android.os.Parcel;
+
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Objects;
+
+/**
+ * Class that describes static IP configuration.
+ *
+ * This class is different from LinkProperties because it represents
+ * configuration intent. The general contract is that if we can represent
+ * a configuration here, then we should be able to configure it on a network.
+ * The intent is that it closely match the UI we have for configuring networks.
+ *
+ * In contrast, LinkProperties represents current state. It is much more
+ * expressive. For example, it supports multiple IP addresses, multiple routes,
+ * stacked interfaces, and so on. Because LinkProperties is so expressive,
+ * using it to represent configuration intent as well as current state causes
+ * problems. For example, we could unknowingly save a configuration that we are
+ * not in fact capable of applying, or we could save a configuration that the
+ * UI cannot display, which has the potential for malicious code to hide
+ * hostile or unexpected configuration from the user: see, for example,
+ * http://b/12663469 and http://b/16893413 .
+ *
+ * @hide
+ */
+public class StaticIpConfiguration implements Parcelable {
+ public LinkAddress ipAddress;
+ public InetAddress gateway;
+ public final ArrayList<InetAddress> dnsServers;
+ public String domains;
+
+ public StaticIpConfiguration() {
+ dnsServers = new ArrayList<InetAddress>();
+ }
+
+ public StaticIpConfiguration(StaticIpConfiguration source) {
+ this();
+ if (source != null) {
+ // All of these except dnsServers are immutable, so no need to make copies.
+ ipAddress = source.ipAddress;
+ gateway = source.gateway;
+ dnsServers.addAll(source.dnsServers);
+ domains = source.domains;
+ }
+ }
+
+ public void clear() {
+ ipAddress = null;
+ gateway = null;
+ dnsServers.clear();
+ domains = null;
+ }
+
+ /**
+ * Returns the network routes specified by this object. Will typically include a
+ * directly-connected route for the IP address's local subnet and a default route.
+ */
+ public List<RouteInfo> getRoutes(String iface) {
+ List<RouteInfo> routes = new ArrayList<RouteInfo>(2);
+ if (ipAddress != null) {
+ routes.add(new RouteInfo(ipAddress, null, iface));
+ }
+ if (gateway != null) {
+ routes.add(new RouteInfo((LinkAddress) null, gateway, iface));
+ }
+ return routes;
+ }
+
+ /**
+ * Returns a LinkProperties object expressing the data in this object. Note that the information
+ * contained in the LinkProperties will not be a complete picture of the link's configuration,
+ * because any configuration information that is obtained dynamically by the network (e.g.,
+ * IPv6 configuration) will not be included.
+ */
+ public LinkProperties toLinkProperties(String iface) {
+ LinkProperties lp = new LinkProperties();
+ lp.setInterfaceName(iface);
+ if (ipAddress != null) {
+ lp.addLinkAddress(ipAddress);
+ }
+ for (RouteInfo route : getRoutes(iface)) {
+ lp.addRoute(route);
+ }
+ for (InetAddress dns : dnsServers) {
+ lp.addDnsServer(dns);
+ }
+ return lp;
+ }
+
+ public String toString() {
+ StringBuffer str = new StringBuffer();
+
+ str.append("IP address ");
+ if (ipAddress != null ) str.append(ipAddress).append(" ");
+
+ str.append("Gateway ");
+ if (gateway != null) str.append(gateway.getHostAddress()).append(" ");
+
+ str.append(" DNS servers: [");
+ for (InetAddress dnsServer : dnsServers) {
+ str.append(" ").append(dnsServer.getHostAddress());
+ }
+
+ str.append(" ] Domains");
+ if (domains != null) str.append(domains);
+ return str.toString();
+ }
+
+ public int hashCode() {
+ int result = 13;
+ result = 47 * result + (ipAddress == null ? 0 : ipAddress.hashCode());
+ result = 47 * result + (gateway == null ? 0 : gateway.hashCode());
+ result = 47 * result + (domains == null ? 0 : domains.hashCode());
+ result = 47 * result + dnsServers.hashCode();
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) return true;
+
+ if (!(obj instanceof StaticIpConfiguration)) return false;
+
+ StaticIpConfiguration other = (StaticIpConfiguration) obj;
+
+ return other != null &&
+ Objects.equals(ipAddress, other.ipAddress) &&
+ Objects.equals(gateway, other.gateway) &&
+ dnsServers.equals(other.dnsServers) &&
+ Objects.equals(domains, other.domains);
+ }
+
+ /** Implement the Parcelable interface */
+ public static Creator<StaticIpConfiguration> CREATOR =
+ new Creator<StaticIpConfiguration>() {
+ public StaticIpConfiguration createFromParcel(Parcel in) {
+ StaticIpConfiguration s = new StaticIpConfiguration();
+ readFromParcel(s, in);
+ return s;
+ }
+
+ public StaticIpConfiguration[] newArray(int size) {
+ return new StaticIpConfiguration[size];
+ }
+ };
+
+ /** Implement the Parcelable interface */
+ public int describeContents() {
+ return 0;
+ }
+
+ /** Implement the Parcelable interface */
+ public void writeToParcel(Parcel dest, int flags) {
+ dest.writeParcelable(ipAddress, flags);
+ NetworkUtils.parcelInetAddress(dest, gateway, flags);
+ dest.writeInt(dnsServers.size());
+ for (InetAddress dnsServer : dnsServers) {
+ NetworkUtils.parcelInetAddress(dest, dnsServer, flags);
+ }
+ }
+
+ protected static void readFromParcel(StaticIpConfiguration s, Parcel in) {
+ s.ipAddress = in.readParcelable(null);
+ s.gateway = NetworkUtils.unparcelInetAddress(in);
+ s.dnsServers.clear();
+ int size = in.readInt();
+ for (int i = 0; i < size; i++) {
+ s.dnsServers.add(NetworkUtils.unparcelInetAddress(in));
+ }
+ }
+}
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index e4ec1cd..5e77d28 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -5190,6 +5190,12 @@
public static final String ADB_ENABLED = "adb_enabled";
/**
+ * Whether Views are allowed to save their attribute data.
+ * @hide
+ */
+ public static final String DEBUG_VIEW_ATTRIBUTES = "debug_view_attributes";
+
+ /**
* Whether assisted GPS should be enabled or not.
* @hide
*/
diff --git a/core/java/android/transition/ChangeImageTransform.java b/core/java/android/transition/ChangeImageTransform.java
index 2b26756..4b230eb 100644
--- a/core/java/android/transition/ChangeImageTransform.java
+++ b/core/java/android/transition/ChangeImageTransform.java
@@ -182,6 +182,7 @@
if (endMatrix == null) {
endMatrix = Matrix.IDENTITY_MATRIX;
}
+ ANIMATED_TRANSFORM_PROPERTY.set(imageView, startMatrix);
animator = createMatrixAnimator(imageView, startMatrix, endMatrix);
}
return animator;
diff --git a/core/java/android/transition/TransitionSet.java b/core/java/android/transition/TransitionSet.java
index 83c60af..68af2d1 100644
--- a/core/java/android/transition/TransitionSet.java
+++ b/core/java/android/transition/TransitionSet.java
@@ -151,6 +151,31 @@
}
/**
+ * Returns the number of child transitions in the TransitionSet.
+ *
+ * @return The number of child transitions in the TransitionSet.
+ * @see #addTransition(Transition)
+ * @see #getTransitionAt(int)
+ */
+ public int getTransitionCount() {
+ return mTransitions.size();
+ }
+
+ /**
+ * Returns the child Transition at the specified position in the TransitionSet.
+ *
+ * @param index The position of the Transition to retrieve.
+ * @see #addTransition(Transition)
+ * @see #getTransitionCount()
+ */
+ public Transition getTransitionAt(int index) {
+ if (index < 0 || index >= mTransitions.size()) {
+ return null;
+ }
+ return mTransitions.get(index);
+ }
+
+ /**
* Setting a non-negative duration on a TransitionSet causes all of the child
* transitions (current and future) to inherit this duration.
*
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index e56581b..cec7e63 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -700,6 +700,13 @@
public static final String DEBUG_LAYOUT_PROPERTY = "debug.layout";
/**
+ * When set to true, this view will save its attribute data.
+ *
+ * @hide
+ */
+ public static boolean mDebugViewAttributes = false;
+
+ /**
* Used to mark a View that has no ID.
*/
public static final int NO_ID = -1;
@@ -3254,6 +3261,7 @@
* This field should be made private, so it is hidden from the SDK.
* {@hide}
*/
+ @ViewDebug.ExportedProperty(deepExport = true)
protected Context mContext;
private final Resources mResources;
@@ -3524,6 +3532,18 @@
GhostView mGhostView;
/**
+ * Holds pairs of adjacent attribute data: attribute name followed by its value.
+ * @hide
+ */
+ @ViewDebug.ExportedProperty(category = "attributes", hasAdjacentMapping = true)
+ public String[] mAttributes;
+
+ /**
+ * Maps a Resource id to its name.
+ */
+ private static SparseArray<String> mAttributeMap;
+
+ /**
* Simple constructor to use when creating a view from code.
*
* @param context The Context the view is running in, through which it can
@@ -3641,6 +3661,10 @@
final TypedArray a = context.obtainStyledAttributes(
attrs, com.android.internal.R.styleable.View, defStyleAttr, defStyleRes);
+ if (mDebugViewAttributes) {
+ saveAttributeData(attrs, a);
+ }
+
Drawable background = null;
int leftPadding = -1;
@@ -4136,6 +4160,51 @@
mRenderNode = RenderNode.create(getClass().getName());
}
+ private static SparseArray<String> getAttributeMap() {
+ if (mAttributeMap == null) {
+ mAttributeMap = new SparseArray<String>();
+ }
+ return mAttributeMap;
+ }
+
+ private void saveAttributeData(AttributeSet attrs, TypedArray a) {
+ int length = ((attrs == null ? 0 : attrs.getAttributeCount()) + a.getIndexCount()) * 2;
+ mAttributes = new String[length];
+
+ int i = 0;
+ if (attrs != null) {
+ for (i = 0; i < attrs.getAttributeCount(); i += 2) {
+ mAttributes[i] = attrs.getAttributeName(i);
+ mAttributes[i + 1] = attrs.getAttributeValue(i);
+ }
+
+ }
+
+ SparseArray<String> attributeMap = getAttributeMap();
+ for (int j = 0; j < a.length(); ++j) {
+ if (a.hasValue(j)) {
+ try {
+ int resourceId = a.getResourceId(j, 0);
+ if (resourceId == 0) {
+ continue;
+ }
+
+ String resourceName = attributeMap.get(resourceId);
+ if (resourceName == null) {
+ resourceName = a.getResources().getResourceName(resourceId);
+ attributeMap.put(resourceId, resourceName);
+ }
+
+ mAttributes[i] = resourceName;
+ mAttributes[i + 1] = a.getText(j).toString();
+ i += 2;
+ } catch (Resources.NotFoundException e) {
+ // if we can't get the resource name, we just ignore it
+ }
+ }
+ }
+ }
+
public String toString() {
StringBuilder out = new StringBuilder(128);
out.append(getClass().getName());
diff --git a/core/java/android/view/ViewDebug.java b/core/java/android/view/ViewDebug.java
index 4d9a8cc..6c66eb0 100644
--- a/core/java/android/view/ViewDebug.java
+++ b/core/java/android/view/ViewDebug.java
@@ -187,6 +187,15 @@
* @return true if the supported values should be formatted as a hex string.
*/
boolean formatToHexString() default false;
+
+ /**
+ * Indicates whether or not the key to value mappings are held in adjacent indices.
+ *
+ * Note: Applies only to fields and methods that return String[].
+ *
+ * @return true if the key to value mappings are held in adjacent indices.
+ */
+ boolean hasAdjacentMapping() default false;
}
/**
@@ -1056,7 +1065,6 @@
Class<?> klass, String prefix) throws IOException {
final Method[] methods = getExportedPropertyMethods(klass);
-
int count = methods.length;
for (int i = 0; i < count; i++) {
final Method method = methods[i];
@@ -1108,6 +1116,19 @@
exportUnrolledArray(context, out, property, array, valuePrefix, suffix);
continue;
+ } else if (returnType == String[].class) {
+ final String[] array = (String[]) methodValue;
+ if (property.hasAdjacentMapping() && array != null) {
+ for (int j = 0; j < array.length; j += 2) {
+ if (array[j] != null) {
+ writeEntry(out, categoryPrefix + prefix, array[j], "()",
+ array[j + 1] == null ? "null" : array[j + 1]);
+ }
+
+ }
+ }
+
+ continue;
} else if (!returnType.isPrimitive()) {
if (property.deepExport()) {
dumpViewProperties(context, methodValue, out, prefix + property.prefix());
@@ -1187,6 +1208,18 @@
exportUnrolledArray(context, out, property, array, valuePrefix, suffix);
continue;
+ } else if (type == String[].class) {
+ final String[] array = (String[]) field.get(view);
+ if (property.hasAdjacentMapping() && array != null) {
+ for (int j = 0; j < array.length; j += 2) {
+ if (array[j] != null) {
+ writeEntry(out, categoryPrefix + prefix, array[j], "",
+ array[j + 1] == null ? "null" : array[j + 1]);
+ }
+ }
+ }
+
+ continue;
} else if (!type.isPrimitive()) {
if (property.deepExport()) {
dumpViewProperties(context, field.get(view), out, prefix +
diff --git a/core/jni/android_net_NetUtils.cpp b/core/jni/android_net_NetUtils.cpp
index 32cf286..5bd38f3 100644
--- a/core/jni/android_net_NetUtils.cpp
+++ b/core/jni/android_net_NetUtils.cpp
@@ -69,9 +69,8 @@
*/
static struct fieldIds {
jmethodID clear;
- jmethodID setInterfaceName;
- jmethodID addLinkAddress;
- jmethodID addGateway;
+ jmethodID setIpAddress;
+ jmethodID setGateway;
jmethodID addDns;
jmethodID setDomains;
jmethodID setServerAddress;
@@ -130,21 +129,16 @@
if (result == 0) {
env->CallVoidMethod(dhcpResults, dhcpResultsFieldIds.clear);
- // set mIfaceName
- // dhcpResults->setInterfaceName(ifname)
- env->CallVoidMethod(dhcpResults, dhcpResultsFieldIds.setInterfaceName, ifname);
-
// set the linkAddress
// dhcpResults->addLinkAddress(inetAddress, prefixLength)
- result = env->CallBooleanMethod(dhcpResults, dhcpResultsFieldIds.addLinkAddress,
+ result = env->CallBooleanMethod(dhcpResults, dhcpResultsFieldIds.setIpAddress,
env->NewStringUTF(ipaddr), prefixLength);
}
if (result == 0) {
// set the gateway
- // dhcpResults->addGateway(gateway)
result = env->CallBooleanMethod(dhcpResults,
- dhcpResultsFieldIds.addGateway, env->NewStringUTF(gateway));
+ dhcpResultsFieldIds.setGateway, env->NewStringUTF(gateway));
}
if (result == 0) {
@@ -279,12 +273,10 @@
LOG_FATAL_IF(dhcpResultsClass == NULL, "Unable to find class android/net/DhcpResults");
dhcpResultsFieldIds.clear =
env->GetMethodID(dhcpResultsClass, "clear", "()V");
- dhcpResultsFieldIds.setInterfaceName =
- env->GetMethodID(dhcpResultsClass, "setInterfaceName", "(Ljava/lang/String;)V");
- dhcpResultsFieldIds.addLinkAddress =
- env->GetMethodID(dhcpResultsClass, "addLinkAddress", "(Ljava/lang/String;I)Z");
- dhcpResultsFieldIds.addGateway =
- env->GetMethodID(dhcpResultsClass, "addGateway", "(Ljava/lang/String;)Z");
+ dhcpResultsFieldIds.setIpAddress =
+ env->GetMethodID(dhcpResultsClass, "setIpAddress", "(Ljava/lang/String;I)Z");
+ dhcpResultsFieldIds.setGateway =
+ env->GetMethodID(dhcpResultsClass, "setGateway", "(Ljava/lang/String;)Z");
dhcpResultsFieldIds.addDns =
env->GetMethodID(dhcpResultsClass, "addDns", "(Ljava/lang/String;)Z");
dhcpResultsFieldIds.setDomains =
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index df77789..157147e 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -1249,13 +1249,13 @@
android:description="@string/permdesc_use_sip"
android:label="@string/permlab_use_sip" />
- <!-- @SystemApi Allows an application to request CallHandlerService implementations.
+ <!-- @SystemApi Allows an application to bind to InCallService implementations.
@hide -->
- <permission android:name="android.permission.BIND_CALL_SERVICE"
+ <permission android:name="android.permission.BIND_INCALL_SERVICE"
android:permissionGroup="android.permission-group.PHONE_CALLS"
android:protectionLevel="system|signature"
- android:description="@string/permdesc_bind_call_service"
- android:label="@string/permlab_bind_call_service" />
+ android:description="@string/permdesc_bind_incall_service"
+ android:label="@string/permlab_bind_incall_service" />
<!-- @SystemApi Allows an application to bind to ConnectionService implementations.
@hide -->
@@ -1265,6 +1265,14 @@
android:description="@string/permdesc_bind_connection_service"
android:label="@string/permlab_bind_connection_service" />
+ <!-- @SystemApi Allows an application to control the in-call experience.
+ @hide -->
+ <permission android:name="android.permission.CONTROL_INCALL_EXPERIENCE"
+ android:permissionGroup="android.permission-group.PHONE_CALLS"
+ android:protectionLevel="system|signature"
+ android:description="@string/permdesc_control_incall_experience"
+ android:label="@string/permlab_control_incall_experience" />
+
<!-- ================================== -->
<!-- Permissions for sdcard interaction -->
<!-- ================================== -->
diff --git a/core/res/res/drawable/stat_notify_disabled_data.xml b/core/res/res/drawable/stat_notify_disabled_data.xml
index 2f6ffaf..9089d08 100644
--- a/core/res/res/drawable/stat_notify_disabled_data.xml
+++ b/core/res/res/drawable/stat_notify_disabled_data.xml
@@ -18,17 +18,7 @@
android:height="24dp"
android:viewportWidth="48.0"
android:viewportHeight="48.0">
-
<path
android:fillColor="#FFFFFFFF"
- android:pathData="M40.709,4.5l-6.604,7.337 0.0,16.601 6.604,6.604z"/>
- <path
- android:fillColor="#FFFFFFFF"
- android:pathData="M32.305,13.838l-6.0629997,6.7370005 6.0629997,6.0629997z"/>
- <path
- android:fillColor="#FFFFFFFF"
- android:pathData="M15.498,40.5l0.0,-7.9869995 -7.205,7.9869995z"/>
- <path
- android:fillColor="#FFFFFFFF"
- android:pathData="M10.265,9.72l-2.5460005,2.545 9.971001,9.971 3.7139988,3.7140007 -4.105999,4.5619984 0.0,9.988001 6.6019993,0.0 0.0,-12.054001 1.8029995,1.8030014 0.0,10.250999 6.602001,0.0 0.0,-3.6479988 1.7999992,1.7999992 1.8479996,1.8479996 4.670002,4.669998 2.5459976,-2.5459976z"/>
+ android:pathData="M26.000000,4.100000l0.000000,6.100000c6.800000,1.000000 12.000000,6.800000 12.000000,13.800000c0.000000,1.800000 -0.400000,3.500000 -1.000000,5.100000l5.200000,3.100000c1.100000,-2.500000 1.800000,-5.200000 1.800000,-8.100000C44.000000,13.600000 36.099998,5.100000 26.000000,4.100000zM24.000000,38.000000c-7.700000,0.000000 -14.000000,-6.300000 -14.000000,-14.000000c0.000000,-7.100000 5.200000,-12.900000 12.000000,-13.800000L22.000000,4.100000C11.900000,5.100000 4.000000,13.600000 4.000000,24.000000c0.000000,11.000000 8.900000,20.000000 20.000000,20.000000c6.600000,0.000000 12.500000,-3.200000 16.100000,-8.200000l-5.200000,-3.100000C32.299999,36.000000 28.400000,38.000000 24.000000,38.000000z"/>
</vector>
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 0d49838..2936e2b 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -2112,9 +2112,9 @@
<string name="permdesc_use_sip">Allows the app to make and receive SIP calls.</string>
<!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
- <string name="permlab_bind_call_service">interact with in-call screen</string>
+ <string name="permlab_bind_incall_service">interact with in-call screen</string>
<!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
- <string name="permdesc_bind_call_service">Allows the app to control when and how the user sees the in-call screen.</string>
+ <string name="permdesc_bind_incall_service">Allows the app to control when and how the user sees the in-call screen.</string>
<!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
<string name="permlab_bind_connection_service">interact with telephony services</string>
@@ -2122,6 +2122,11 @@
<string name="permdesc_bind_connection_service">Allows the app to interact with telephony services to make/receive calls.</string>
<!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
+ <string name="permlab_control_incall_experience">provide an in-call user experience</string>
+ <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
+ <string name="permdesc_control_incall_experience">Allows the app to provide an in-call user experience.</string>
+
+ <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
<string name="permlab_readNetworkUsageHistory">read historical network usage</string>
<!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
<string name="permdesc_readNetworkUsageHistory">Allows the app to read historical network usage for specific networks and apps.</string>
@@ -4245,15 +4250,15 @@
<string name="data_usage_warning_body">Touch to view usage and settings.</string>
<!-- Notification title when 2G-3G data usage has exceeded limit threshold, and has been disabled. [CHAR LIMIT=32] -->
- <string name="data_usage_3g_limit_title">2G-3G data is off</string>
+ <string name="data_usage_3g_limit_title">2G-3G data limit reached</string>
<!-- Notification title when 4G data usage has exceeded limit threshold, and has been disabled. [CHAR LIMIT=32] -->
- <string name="data_usage_4g_limit_title">4G data is off</string>
+ <string name="data_usage_4g_limit_title">4G data limit reached</string>
<!-- Notification title when mobile data usage has exceeded limit threshold, and has been disabled. [CHAR LIMIT=32] -->
- <string name="data_usage_mobile_limit_title">Cellular data is off</string>
+ <string name="data_usage_mobile_limit_title">Cellular data limit reached</string>
<!-- Notification title when Wi-Fi data usage has exceeded limit threshold, and has been disabled. [CHAR LIMIT=32] -->
- <string name="data_usage_wifi_limit_title">Wi-Fi data is off</string>
+ <string name="data_usage_wifi_limit_title">Wi-Fi data limit reached</string>
<!-- Notification body when data usage has exceeded limit threshold, and has been disabled. [CHAR LIMIT=32] -->
- <string name="data_usage_limit_body">Limit reached</string>
+ <string name="data_usage_limit_body">Data paused for rest of cycle</string>
<!-- Notification title when 2G-3G data usage has exceeded limit threshold. [CHAR LIMIT=32] -->
<string name="data_usage_3g_limit_snoozed_title">2G-3G data limit exceeded</string>
diff --git a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/AccessPointParserHelper.java b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/AccessPointParserHelper.java
index 116a31e..93b16e7 100644
--- a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/AccessPointParserHelper.java
+++ b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/AccessPointParserHelper.java
@@ -26,8 +26,8 @@
import android.net.IpConfiguration.IpAssignment;
import android.net.IpConfiguration.ProxySettings;
import android.net.LinkAddress;
-import android.net.LinkProperties;
import android.net.RouteInfo;
+import android.net.StaticIpConfiguration;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiConfiguration.AuthAlgorithm;
import android.net.wifi.WifiConfiguration.KeyMgmt;
@@ -116,7 +116,7 @@
boolean usercert = false;
WifiConfiguration config = null;
int securityType = NONE;
- LinkProperties mLinkProperties = null;
+ StaticIpConfiguration mStaticIpConfiguration = null;
InetAddress mInetAddr = null;
@Override
@@ -153,7 +153,7 @@
usercert = true;
}
if (tagName.equalsIgnoreCase("ip")) {
- mLinkProperties = new LinkProperties();
+ mStaticIpConfiguration = new StaticIpConfiguration();
ip = true;
}
if (tagName.equalsIgnoreCase("gateway")) {
@@ -173,15 +173,15 @@
@Override
public void endElement(String uri, String localName, String tagName) throws SAXException {
if (tagName.equalsIgnoreCase("accesspoint")) {
- if (mLinkProperties != null) {
+ if (mStaticIpConfiguration != null) {
config.setIpAssignment(IpAssignment.STATIC);
- config.setLinkProperties(mLinkProperties);
+ config.setStaticIpConfiguration(mStaticIpConfiguration);
} else {
config.setIpAssignment(IpAssignment.DHCP);
}
config.setProxySettings(ProxySettings.NONE);
networks.add(config);
- mLinkProperties = null;
+ mStaticIpConfiguration = null;
}
}
@@ -312,7 +312,7 @@
if (!InetAddress.isNumeric(gwAddr)) {
throw new SAXException();
}
- mLinkProperties.addRoute(new RouteInfo(InetAddress.getByName(gwAddr)));
+ mStaticIpConfiguration.gateway = InetAddress.getByName(gwAddr);
} catch (UnknownHostException e) {
throw new SAXException();
}
@@ -324,7 +324,7 @@
if ((nwPrefixLength < 0) || (nwPrefixLength > 32)) {
throw new SAXException();
}
- mLinkProperties.addLinkAddress(new LinkAddress(mInetAddr, nwPrefixLength));
+ mStaticIpConfiguration.ipAddress = new LinkAddress(mInetAddr, nwPrefixLength);
} catch (NumberFormatException e) {
throw new SAXException();
}
@@ -336,7 +336,7 @@
if (!InetAddress.isNumeric(dnsAddr)) {
throw new SAXException();
}
- mLinkProperties.addDnsServer(InetAddress.getByName(dnsAddr));
+ mStaticIpConfiguration.dnsServers.add(InetAddress.getByName(dnsAddr));
} catch (UnknownHostException e) {
throw new SAXException();
}
@@ -348,7 +348,7 @@
if (!InetAddress.isNumeric(dnsAddr)) {
throw new SAXException();
}
- mLinkProperties.addDnsServer(InetAddress.getByName(dnsAddr));
+ mStaticIpConfiguration.dnsServers.add(InetAddress.getByName(dnsAddr));
} catch (UnknownHostException e) {
throw new SAXException();
}
diff --git a/docs/html/google/play/billing/billing_reference.jd b/docs/html/google/play/billing/billing_reference.jd
index e168d70..4f5e65c 100644
--- a/docs/html/google/play/billing/billing_reference.jd
+++ b/docs/html/google/play/billing/billing_reference.jd
@@ -102,15 +102,28 @@
</tr>
<tr>
<td>{@code type}</td>
- <td>Value must be “inapp” for an in-app product or "subs" for
+ <td>Value must be “inapp” for an in-app product or "subs" for
subscriptions.</td>
</tr>
<tr>
<td>{@code price}</td>
- <td>Formatted price of the item, including its currency sign. The price
+ <td>Formatted price of the item, including its currency sign. The price
does not include tax.</td>
</tr>
<tr>
+ <td>{@code price_amount_micros}</td>
+ <td>Price in micro-units, where 1,000,000 micro-units equal one unit of the
+ currency. For example, if {@code price} is {@code "€7.99"}, {@code
+ price_amount_micros} is {@code "7990000"}.</td>
+ </tr>
+ <tr>
+ <td>{@code price_currency_code}</td>
+ <td><a href="http://en.wikipedia.org/wiki/ISO_4217#Active_codes">ISO 4217
+ currency code</a> for {@code price}. For example, if {@code price} is
+ specified in British pounds sterling, {@code price_currency_code} is {@code
+ "GBP"}.</td>
+ </tr>
+ <tr>
<td>{@code title}</td>
<td>Title of the product.</td>
</tr>
diff --git a/graphics/java/android/graphics/Outline.java b/graphics/java/android/graphics/Outline.java
index 3177023..4bf0b71 100644
--- a/graphics/java/android/graphics/Outline.java
+++ b/graphics/java/android/graphics/Outline.java
@@ -18,15 +18,15 @@
import android.annotation.NonNull;
import android.graphics.drawable.Drawable;
-import android.view.View;
/**
* Defines a simple shape, used for bounding graphical regions.
* <p>
- * Can be used with a View, or computed by a Drawable, to drive the shape of shadows cast by a
- * View, or to clip the contents of the View.
+ * Can be computed for a View, or computed by a Drawable, to drive the shape of
+ * shadows cast by a View, or to clip the contents of the View.
*
- * @see View#setOutline(Outline)
+ * @see android.view.ViewOutlineProvider
+ * @see android.view.View#setOutlineProvider(android.view.ViewOutlineProvider)
* @see Drawable#getOutline(Outline)
*/
public final class Outline {
@@ -79,21 +79,27 @@
/**
* Returns whether the outline can be used to clip a View.
+ * <p>
+ * Currently, only Outlines that can be represented as a rectangle, circle,
+ * or round rect support clipping.
*
- * Currently, only outlines that can be represented as a rectangle, circle, or round rect
- * support clipping.
- *
- * @see {@link View#setClipToOutline(boolean)}
+ * @see {@link android.view.View#setClipToOutline(boolean)}
*/
public boolean canClip() {
return !isEmpty() && mRect != null;
}
/**
- * Sets the alpha represented by the Outline.
- *
- * Content producing a fully opaque (alpha = 1.0f) outline is assumed by the drawing system
- * to fully cover content beneath it, meaning content beneath may be optimized away.
+ * Sets the alpha represented by the Outline - the degree to which the
+ * producer is guaranteed to be opaque over the Outline's shape.
+ * <p>
+ * An alpha value of <code>0.0f</code> either represents completely
+ * transparent content, or content that isn't guaranteed to fill the shape
+ * it publishes.
+ * <p>
+ * Content producing a fully opaque (alpha = <code>1.0f</code>) outline is
+ * assumed by the drawing system to fully cover content beneath it,
+ * meaning content beneath may be optimized away.
*/
public void setAlpha(float alpha) {
mAlpha = alpha;
@@ -130,7 +136,8 @@
}
/**
- * Sets the Outline to the rounded rect defined by the input rect, and corner radius.
+ * Sets the Outline to the rounded rect defined by the input rect, and
+ * corner radius.
*/
public void setRect(int left, int top, int right, int bottom) {
setRoundRect(left, top, right, bottom, 0.0f);
@@ -145,7 +152,7 @@
/**
* Sets the Outline to the rounded rect defined by the input rect, and corner radius.
- *
+ * <p>
* Passing a zero radius is equivalent to calling {@link #setRect(int, int, int, int)}
*/
public void setRoundRect(int left, int top, int right, int bottom, float radius) {
@@ -196,7 +203,8 @@
}
/**
- * Sets the Constructs an Outline from a {@link android.graphics.Path#isConvex() convex path}.
+ * Sets the Constructs an Outline from a
+ * {@link android.graphics.Path#isConvex() convex path}.
*/
public void setConvexPath(@NonNull Path convexPath) {
if (convexPath.isEmpty()) {
diff --git a/graphics/java/android/graphics/drawable/GradientDrawable.java b/graphics/java/android/graphics/drawable/GradientDrawable.java
index a383aab..29b9141 100644
--- a/graphics/java/android/graphics/drawable/GradientDrawable.java
+++ b/graphics/java/android/graphics/drawable/GradientDrawable.java
@@ -820,7 +820,7 @@
@Override
public int getOpacity() {
- return (mAlpha == 255 && mGradientState.mOpaque) ?
+ return (mAlpha == 255 && mGradientState.mOpaqueOverBounds) ?
PixelFormat.OPAQUE : PixelFormat.TRANSLUCENT;
}
@@ -1413,7 +1413,8 @@
public void getOutline(Outline outline) {
final GradientState st = mGradientState;
final Rect bounds = getBounds();
- outline.setAlpha(mAlpha / 255.0f);
+ // only report non-zero alpha if shape being drawn is opaque
+ outline.setAlpha(st.mOpaqueOverShape ? (mAlpha / 255.0f) : 0.0f);
switch (st.mShape) {
case RECTANGLE:
@@ -1492,7 +1493,8 @@
private int mGradientRadiusType = RADIUS_TYPE_PIXELS;
private boolean mUseLevel;
private boolean mUseLevelForShape;
- private boolean mOpaque;
+ private boolean mOpaqueOverBounds;
+ private boolean mOpaqueOverShape;
int[] mThemeAttrs;
int[] mAttrSize;
@@ -1544,7 +1546,7 @@
mGradientRadiusType = state.mGradientRadiusType;
mUseLevel = state.mUseLevel;
mUseLevelForShape = state.mUseLevelForShape;
- mOpaque = state.mOpaque;
+ mOpaqueOverBounds = state.mOpaqueOverBounds;
mThemeAttrs = state.mThemeAttrs;
mAttrSize = state.mAttrSize;
mAttrGradient = state.mAttrGradient;
@@ -1606,40 +1608,36 @@
}
private void computeOpacity() {
- if (mShape != RECTANGLE) {
- mOpaque = false;
- return;
- }
+ mOpaqueOverBounds = false;
+ mOpaqueOverShape = false;
- if (mRadius > 0 || mRadiusArray != null) {
- mOpaque = false;
- return;
- }
-
+ // First test opacity of all colors
if (mStrokeWidth > 0) {
if (mStrokeColorStateList != null) {
if (!mStrokeColorStateList.isOpaque()) {
- mOpaque = false;
return;
}
}
}
if (mColorStateList != null && !mColorStateList.isOpaque()) {
- mOpaque = false;
return;
}
if (mColors != null) {
for (int i = 0; i < mColors.length; i++) {
if (!isOpaque(mColors[i])) {
- mOpaque = false;
return;
}
}
}
- mOpaque = true;
+ // Colors are opaque, so opaqueOverShape=true,
+ mOpaqueOverShape = true;
+ // and opaqueOverBounds=true if shape fills bounds
+ mOpaqueOverBounds = mShape == RECTANGLE
+ && mRadius <= 0
+ && mRadiusArray == null;
}
private static boolean isOpaque(int color) {
diff --git a/libs/hwui/DisplayListOp.h b/libs/hwui/DisplayListOp.h
index c6d3db7..1032a75 100644
--- a/libs/hwui/DisplayListOp.h
+++ b/libs/hwui/DisplayListOp.h
@@ -208,6 +208,8 @@
// ensure that local bounds cover mapped bounds
if (!state.mMatrix.isSimple()) return false;
+ if (state.mRoundRectClipState) return false;
+
// check state/paint for transparency
if (mPaint) {
if (mPaint->getShader() && !mPaint->getShader()->isOpaque()) {
diff --git a/media/java/android/media/AudioManager.java b/media/java/android/media/AudioManager.java
index 6a76a71..e69c456 100644
--- a/media/java/android/media/AudioManager.java
+++ b/media/java/android/media/AudioManager.java
@@ -2332,18 +2332,21 @@
}
/**
- * Registers a {@link RemoteController} instance for it to receive media metadata updates
- * and playback state information from applications using {@link RemoteControlClient}, and
- * control their playback.
- * <p>Registration requires the {@link OnClientUpdateListener} listener to be one of the
- * enabled notification listeners (see
+ * Registers a {@link RemoteController} instance for it to receive media
+ * metadata updates and playback state information from applications using
+ * {@link RemoteControlClient}, and control their playback.
+ * <p>
+ * Registration requires the {@link OnClientUpdateListener} listener to be
+ * one of the enabled notification listeners (see
* {@link android.service.notification.NotificationListenerService}).
+ *
* @param rctlr the object to register.
- * @return true if the {@link RemoteController} was successfully registered, false if an
- * error occurred, due to an internal system error, or insufficient permissions.
+ * @return true if the {@link RemoteController} was successfully registered,
+ * false if an error occurred, due to an internal system error, or
+ * insufficient permissions.
* @deprecated Use
- * {@link MediaSessionManager#addActiveSessionsListener(android.media.session.MediaSessionManager.SessionListener, ComponentName)}
- * and {@link MediaController} instead.
+ * {@link MediaSessionManager#addOnActiveSessionsChangedListener(android.media.session.MediaSessionManager.OnActiveSessionsChangedListener, ComponentName)}
+ * and {@link MediaController} instead.
*/
@Deprecated
public boolean registerRemoteController(RemoteController rctlr) {
@@ -2355,12 +2358,14 @@
}
/**
- * Unregisters a {@link RemoteController}, causing it to no longer receive media metadata and
- * playback state information, and no longer be capable of controlling playback.
+ * Unregisters a {@link RemoteController}, causing it to no longer receive
+ * media metadata and playback state information, and no longer be capable
+ * of controlling playback.
+ *
* @param rctlr the object to unregister.
* @deprecated Use
- * {@link MediaSessionManager#removeActiveSessionsListener(android.media.session.MediaSessionManager.SessionListener)}
- * instead.
+ * {@link MediaSessionManager#removeOnActiveSessionsChangedListener(android.media.session.MediaSessionManager.OnActiveSessionsChangedListener)}
+ * instead.
*/
@Deprecated
public void unregisterRemoteController(RemoteController rctlr) {
diff --git a/media/java/android/media/MediaPlayer.java b/media/java/android/media/MediaPlayer.java
index 2fa0c93..7c3b4fc 100644
--- a/media/java/android/media/MediaPlayer.java
+++ b/media/java/android/media/MediaPlayer.java
@@ -1049,8 +1049,17 @@
private void setDataSource(String path, String[] keys, String[] values)
throws IOException, IllegalArgumentException, SecurityException, IllegalStateException {
final Uri uri = Uri.parse(path);
- if ("file".equals(uri.getScheme())) {
+ final String scheme = uri.getScheme();
+ if ("file".equals(scheme)) {
path = uri.getPath();
+ } else if (scheme != null) {
+ // handle non-file sources
+ nativeSetDataSource(
+ MediaHTTPService.createHttpServiceBinderIfNecessary(path),
+ path,
+ keys,
+ values);
+ return;
}
final File file = new File(path);
@@ -1060,20 +1069,10 @@
setDataSource(fd);
is.close();
} else {
- _setDataSource(path, keys, values);
+ throw new IOException("setDataSource failed.");
}
}
- private void _setDataSource(
- String path, String[] keys, String[] values)
- throws IOException, IllegalArgumentException, SecurityException, IllegalStateException {
- nativeSetDataSource(
- MediaHTTPService.createHttpServiceBinderIfNecessary(path),
- path,
- keys,
- values);
- }
-
private native void nativeSetDataSource(
IBinder httpServiceBinder, String path, String[] keys, String[] values)
throws IOException, IllegalArgumentException, SecurityException, IllegalStateException;
diff --git a/media/java/android/media/RemoteController.java b/media/java/android/media/RemoteController.java
index adc8391..f378cef 100644
--- a/media/java/android/media/RemoteController.java
+++ b/media/java/android/media/RemoteController.java
@@ -74,7 +74,7 @@
private MetadataEditor mMetadataEditor;
private MediaSessionManager mSessionManager;
- private MediaSessionManager.SessionListener mSessionListener;
+ private MediaSessionManager.OnActiveSessionsChangedListener mSessionListener;
private MediaController.Callback mSessionCb = new MediaControllerCallback();
/**
@@ -140,7 +140,7 @@
mAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
mSessionManager = (MediaSessionManager) context
.getSystemService(Context.MEDIA_SESSION_SERVICE);
- mSessionListener = new TopTransportSessionListener(context);
+ mSessionListener = new TopTransportSessionListener();
if (ActivityManager.isLowRamDeviceStatic()) {
mMaxBitmapDimension = MAX_BITMAP_DIMENSION;
@@ -710,11 +710,8 @@
* Listens for changes to the active session stack and replaces the
* currently tracked session if it has changed.
*/
- private class TopTransportSessionListener extends MediaSessionManager.SessionListener {
-
- public TopTransportSessionListener(Context context) {
- super(context);
- }
+ private class TopTransportSessionListener implements
+ MediaSessionManager.OnActiveSessionsChangedListener {
@Override
public void onActiveSessionsChanged(List<MediaController> controllers) {
@@ -792,7 +789,7 @@
void startListeningToSessions() {
final ComponentName listenerComponent = new ComponentName(mContext,
mOnClientUpdateListener.getClass());
- mSessionManager.addActiveSessionsListener(mSessionListener, listenerComponent,
+ mSessionManager.addOnActiveSessionsChangedListener(mSessionListener, listenerComponent,
UserHandle.myUserId(), null);
mSessionListener.onActiveSessionsChanged(mSessionManager
.getActiveSessions(listenerComponent));
@@ -806,7 +803,7 @@
* @hide
*/
void stopListeningToSessions() {
- mSessionManager.removeActiveSessionsListener(mSessionListener);
+ mSessionManager.removeOnActiveSessionsChangedListener(mSessionListener);
if (DEBUG) {
Log.d(TAG, "Unregistered session listener for user "
+ UserHandle.myUserId());
diff --git a/media/java/android/media/session/MediaController.java b/media/java/android/media/session/MediaController.java
index 63c85f8..074e5ad 100644
--- a/media/java/android/media/session/MediaController.java
+++ b/media/java/android/media/session/MediaController.java
@@ -185,7 +185,7 @@
*
* @return The current play queue or null.
*/
- public @Nullable List<MediaSession.Track> getQueue() {
+ public @Nullable List<MediaSession.Item> getQueue() {
try {
ParceledListSlice queue = mSessionBinder.getQueue();
if (queue != null) {
@@ -259,18 +259,18 @@
}
/**
- * Get the current volume info for this session.
+ * Get the current audio info for this session.
*
- * @return The current volume info or null.
+ * @return The current audio info or null.
*/
- public @Nullable VolumeInfo getVolumeInfo() {
+ public @Nullable AudioInfo getAudioInfo() {
try {
ParcelableVolumeInfo result = mSessionBinder.getVolumeAttributes();
- return new VolumeInfo(result.volumeType, result.audioAttrs, result.controlType,
+ return new AudioInfo(result.volumeType, result.audioAttrs, result.controlType,
result.maxVolume, result.currentVolume);
} catch (RemoteException e) {
- Log.wtf(TAG, "Error calling getVolumeInfo.", e);
+ Log.wtf(TAG, "Error calling getAudioInfo.", e);
}
return null;
}
@@ -305,7 +305,7 @@
* {@link VolumeProvider#VOLUME_CONTROL_ABSOLUTE}. The flags in
* {@link AudioManager} may be used to affect the handling.
*
- * @see #getVolumeInfo()
+ * @see #getAudioInfo()
* @param value The value to set it to, between 0 and the reported max.
* @param flags Any flags to pass with the command.
*/
@@ -326,7 +326,7 @@
* {@link VolumeProvider#VOLUME_CONTROL_ABSOLUTE}. The flags in
* {@link AudioManager} may be used to affect the handling.
*
- * @see #getVolumeInfo()
+ * @see #getAudioInfo()
* @param direction The direction to adjust the volume in.
* @param flags Any flags to pass with the command.
*/
@@ -544,13 +544,14 @@
}
/**
- * Override to handle changes to tracks in the queue.
+ * Override to handle changes to items in the queue.
*
- * @param queue A list of tracks in the current play queue. It should include the currently
- * playing track as well as previous and upcoming tracks if applicable.
- * @see MediaSession.Track
+ * @param queue A list of items in the current play queue. It should
+ * include the currently playing item as well as previous and
+ * upcoming items if applicable.
+ * @see MediaSession.Item
*/
- public void onQueueChanged(@Nullable List<MediaSession.Track> queue) {
+ public void onQueueChanged(@Nullable List<MediaSession.Item> queue) {
}
/**
@@ -572,11 +573,11 @@
}
/**
- * Override to handle changes to the volume info.
+ * Override to handle changes to the audio info.
*
- * @param info The current volume info for this session.
+ * @param info The current audio info for this session.
*/
- public void onVolumeInfoChanged(VolumeInfo info) {
+ public void onAudioInfoChanged(AudioInfo info) {
}
}
@@ -638,14 +639,14 @@
}
/**
- * Play a track with a specific id in the play queue.
- * If you specify an id that is not in the play queue, the behavior is undefined.
+ * Play an item with a specific id in the play queue. If you specify an
+ * id that is not in the play queue, the behavior is undefined.
*/
- public void skipToTrack(long id) {
+ public void skipToItem(long id) {
try {
mSessionBinder.skipToTrack(id);
} catch (RemoteException e) {
- Log.wtf(TAG, "Error calling skipToTrack(" + id + ").", e);
+ Log.wtf(TAG, "Error calling skipToItem(" + id + ").", e);
}
}
@@ -784,9 +785,9 @@
}
/**
- * Holds information about the way volume is handled for this session.
+ * Holds information about the way audio is handled for this session.
*/
- public static final class VolumeInfo {
+ public static final class AudioInfo {
private final int mVolumeType;
private final int mVolumeControl;
private final int mMaxVolume;
@@ -796,7 +797,7 @@
/**
* @hide
*/
- public VolumeInfo(int type, AudioAttributes attrs, int control, int max, int current) {
+ public AudioInfo(int type, AudioAttributes attrs, int control, int max, int current) {
mVolumeType = type;
mAudioAttrs = attrs;
mVolumeControl = control;
@@ -904,7 +905,7 @@
@Override
public void onQueueChanged(ParceledListSlice parceledQueue) {
- List<MediaSession.Track> queue = parceledQueue.getList();
+ List<MediaSession.Item> queue = parceledQueue.getList();
MediaController controller = mController.get();
if (controller != null) {
controller.postMessage(MSG_UPDATE_QUEUE, queue, null);
@@ -931,7 +932,7 @@
public void onVolumeInfoChanged(ParcelableVolumeInfo pvi) {
MediaController controller = mController.get();
if (controller != null) {
- VolumeInfo info = new VolumeInfo(pvi.volumeType, pvi.audioAttrs, pvi.controlType,
+ AudioInfo info = new AudioInfo(pvi.volumeType, pvi.audioAttrs, pvi.controlType,
pvi.maxVolume, pvi.currentVolume);
controller.postMessage(MSG_UPDATE_VOLUME, info, null);
}
@@ -960,7 +961,7 @@
mCallback.onMetadataChanged((MediaMetadata) msg.obj);
break;
case MSG_UPDATE_QUEUE:
- mCallback.onQueueChanged((List<MediaSession.Track>) msg.obj);
+ mCallback.onQueueChanged((List<MediaSession.Item>) msg.obj);
break;
case MSG_UPDATE_QUEUE_TITLE:
mCallback.onQueueTitleChanged((CharSequence) msg.obj);
@@ -969,7 +970,7 @@
mCallback.onExtrasChanged((Bundle) msg.obj);
break;
case MSG_UPDATE_VOLUME:
- mCallback.onVolumeInfoChanged((VolumeInfo) msg.obj);
+ mCallback.onAudioInfoChanged((AudioInfo) msg.obj);
break;
case MSG_DESTROYED:
mCallback.onSessionDestroyed();
diff --git a/media/java/android/media/session/MediaSession.java b/media/java/android/media/session/MediaSession.java
index cf73c2a..2cd161c 100644
--- a/media/java/android/media/session/MediaSession.java
+++ b/media/java/android/media/session/MediaSession.java
@@ -435,18 +435,19 @@
}
/**
- * Update the list of tracks in the play queue. It is an ordered list and should contain the
- * current track, and previous or upcoming tracks if they exist.
- * Specify null if there is no current play queue.
+ * Update the list of items in the play queue. It is an ordered list and
+ * should contain the current item, and previous or upcoming items if they
+ * exist. Specify null if there is no current play queue.
* <p>
- * The queue should be of reasonable size. If the play queue is unbounded within your
- * app, it is better to send a reasonable amount in a sliding window instead.
+ * The queue should be of reasonable size. If the play queue is unbounded
+ * within your app, it is better to send a reasonable amount in a sliding
+ * window instead.
*
- * @param queue A list of tracks in the play queue.
+ * @param queue A list of items in the play queue.
*/
- public void setQueue(@Nullable List<Track> queue) {
+ public void setQueue(@Nullable List<Item> queue) {
try {
- mBinder.setQueue(new ParceledListSlice<Track>(queue));
+ mBinder.setQueue(new ParceledListSlice<Item>(queue));
} catch (RemoteException e) {
Log.wtf("Dead object in setQueue.", e);
}
@@ -512,8 +513,8 @@
postToCallback(CallbackMessageHandler.MSG_PLAY_SEARCH, query, extras);
}
- private void dispatchSkipToTrack(long id) {
- postToCallback(CallbackMessageHandler.MSG_SKIP_TO_TRACK, id);
+ private void dispatchSkipToItem(long id) {
+ postToCallback(CallbackMessageHandler.MSG_SKIP_TO_ITEM, id);
}
private void dispatchPause() {
@@ -782,9 +783,10 @@
}
/**
- * Override to handle requests to play a track with a given id from the play queue.
+ * Override to handle requests to play an item with a given id from the
+ * play queue.
*/
- public void onSkipToTrack(long id) {
+ public void onSkipToItem(long id) {
}
/**
@@ -916,7 +918,7 @@
public void onSkipToTrack(long id) {
MediaSession session = mMediaSession.get();
if (session != null) {
- session.dispatchSkipToTrack(id);
+ session.dispatchSkipToItem(id);
}
}
@@ -1015,12 +1017,12 @@
}
/**
- * A single track that is part of the play queue. It contains information necessary to display
- * a single track in the queue.
+ * A single item that is part of the play queue. It contains information
+ * necessary to display a single item in the queue.
*/
- public static final class Track implements Parcelable {
+ public static final class Item implements Parcelable {
/**
- * This id is reserved. No tracks can be explicitly asigned this id.
+ * This id is reserved. No items can be explicitly asigned this id.
*/
public static final int UNKNOWN_ID = -1;
@@ -1030,22 +1032,23 @@
private final Bundle mExtras;
/**
- * Create a new {@link MediaSession.Track}.
+ * Create a new {@link MediaSession.Item}.
*
- * @param metadata The metadata for this track.
- * @param id An identifier for this track. It must be unique within the play queue.
- * @param uri The uri for this track.
- * @param extras A bundle of extras that can be used to add extra information about the
- * track.
+ * @param metadata The metadata for this item.
+ * @param id An identifier for this item. It must be unique within the
+ * play queue.
+ * @param uri The uri for this item.
+ * @param extras A bundle of extras that can be used to add extra
+ * information about this item.
*/
- private Track(MediaMetadata metadata, long id, Uri uri, Bundle extras) {
+ private Item(MediaMetadata metadata, long id, Uri uri, Bundle extras) {
mMetadata = metadata;
mId = id;
mUri = uri;
mExtras = extras;
}
- private Track(Parcel in) {
+ private Item(Parcel in) {
mMetadata = MediaMetadata.CREATOR.createFromParcel(in);
mId = in.readLong();
mUri = Uri.CREATOR.createFromParcel(in);
@@ -1053,35 +1056,35 @@
}
/**
- * Get the metadata for this track.
+ * Get the metadata for this item.
*/
public MediaMetadata getMetadata() {
return mMetadata;
}
/**
- * Get the id for this track.
+ * Get the id for this item.
*/
public long getId() {
return mId;
}
/**
- * Get the Uri for this track.
+ * Get the Uri for this item.
*/
public Uri getUri() {
return mUri;
}
/**
- * Get the extras for this track.
+ * Get the extras for this item.
*/
public Bundle getExtras() {
return mExtras;
}
/**
- * Builder for {@link MediaSession.Track} objects.
+ * Builder for {@link MediaSession.Item} objects.
*/
public static final class Builder {
private final MediaMetadata mMetadata;
@@ -1096,15 +1099,15 @@
public Builder(MediaMetadata metadata, long id, Uri uri) {
if (metadata == null) {
throw new IllegalArgumentException(
- "You must specify a non-null MediaMetadata to build a Track.");
+ "You must specify a non-null MediaMetadata to build an Item.");
}
if (uri == null) {
throw new IllegalArgumentException(
- "You must specify a non-null Uri to build a Track.");
+ "You must specify a non-null Uri to build an Item.");
}
if (id == UNKNOWN_ID) {
throw new IllegalArgumentException(
- "You must specify an id other than UNKNOWN_ID to build a Track.");
+ "You must specify an id other than UNKNOWN_ID to build an Item.");
}
mMetadata = metadata;
mId = id;
@@ -1112,18 +1115,18 @@
}
/**
- * Set optional extras for the track.
+ * Set optional extras for the item.
*/
- public MediaSession.Track.Builder setExtras(Bundle extras) {
+ public MediaSession.Item.Builder setExtras(Bundle extras) {
mExtras = extras;
return this;
}
/**
- * Create the {@link Track}.
+ * Create the {@link Item}.
*/
- public MediaSession.Track build() {
- return new MediaSession.Track(mMetadata, mId, mUri, mExtras);
+ public MediaSession.Item build() {
+ return new MediaSession.Item(mMetadata, mId, mUri, mExtras);
}
}
@@ -1140,23 +1143,23 @@
return 0;
}
- public static final Creator<MediaSession.Track> CREATOR
- = new Creator<MediaSession.Track>() {
+ public static final Creator<MediaSession.Item> CREATOR
+ = new Creator<MediaSession.Item>() {
@Override
- public MediaSession.Track createFromParcel(Parcel p) {
- return new MediaSession.Track(p);
+ public MediaSession.Item createFromParcel(Parcel p) {
+ return new MediaSession.Item(p);
}
@Override
- public MediaSession.Track[] newArray(int size) {
- return new MediaSession.Track[size];
+ public MediaSession.Item[] newArray(int size) {
+ return new MediaSession.Item[size];
}
};
@Override
public String toString() {
- return "MediaSession.Track {" +
+ return "MediaSession.Item {" +
"Metadata=" + mMetadata +
", Id=" + mId +
", Uri=" + mUri +
@@ -1182,7 +1185,7 @@
private static final int MSG_PLAY = 1;
private static final int MSG_PLAY_URI = 2;
private static final int MSG_PLAY_SEARCH = 3;
- private static final int MSG_SKIP_TO_TRACK = 4;
+ private static final int MSG_SKIP_TO_ITEM = 4;
private static final int MSG_PAUSE = 5;
private static final int MSG_STOP = 6;
private static final int MSG_NEXT = 7;
@@ -1232,8 +1235,8 @@
case MSG_PLAY_SEARCH:
mCallback.onPlayFromSearch((String) msg.obj, msg.getData());
break;
- case MSG_SKIP_TO_TRACK:
- mCallback.onSkipToTrack((Long) msg.obj);
+ case MSG_SKIP_TO_ITEM:
+ mCallback.onSkipToItem((Long) msg.obj);
case MSG_PAUSE:
mCallback.onPause();
break;
diff --git a/media/java/android/media/session/MediaSessionManager.java b/media/java/android/media/session/MediaSessionManager.java
index c2fb5a3..8a1e076 100644
--- a/media/java/android/media/session/MediaSessionManager.java
+++ b/media/java/android/media/session/MediaSessionManager.java
@@ -30,6 +30,7 @@
import android.os.UserHandle;
import android.service.notification.NotificationListenerService;
import android.text.TextUtils;
+import android.util.ArrayMap;
import android.util.Log;
import android.view.KeyEvent;
@@ -50,6 +51,9 @@
public final class MediaSessionManager {
private static final String TAG = "SessionManager";
+ private final ArrayMap<OnActiveSessionsChangedListener, SessionsChangedWrapper> mListeners
+ = new ArrayMap<OnActiveSessionsChangedListener, SessionsChangedWrapper>();
+ private final Object mLock = new Object();
private final ISessionManager mService;
private Context mContext;
@@ -141,10 +145,11 @@
* @param notificationListener The enabled notification listener component.
* May be null.
*/
- public void addActiveSessionsListener(@NonNull SessionListener sessionListener,
+ public void addOnActiveSessionsChangedListener(
+ @NonNull OnActiveSessionsChangedListener sessionListener,
@Nullable ComponentName notificationListener) {
- addActiveSessionsListener(sessionListener, notificationListener, UserHandle.myUserId(),
- null);
+ addOnActiveSessionsChangedListener(sessionListener, notificationListener,
+ UserHandle.myUserId(), null);
}
/**
@@ -163,7 +168,8 @@
* @param handler The handler to post updates on.
* @hide
*/
- public void addActiveSessionsListener(@NonNull SessionListener sessionListener,
+ public void addOnActiveSessionsChangedListener(
+ @NonNull OnActiveSessionsChangedListener sessionListener,
@Nullable ComponentName notificationListener, int userId, @Nullable Handler handler) {
if (sessionListener == null) {
throw new IllegalArgumentException("listener may not be null");
@@ -171,11 +177,18 @@
if (handler == null) {
handler = new Handler();
}
- sessionListener.setHandler(handler);
- try {
- mService.addSessionsListener(sessionListener.mStub, notificationListener, userId);
- } catch (RemoteException e) {
- Log.e(TAG, "Error in addActiveSessionsListener.", e);
+ synchronized (mLock) {
+ if (mListeners.get(sessionListener) != null) {
+ Log.w(TAG, "Attempted to add session listener twice, ignoring.");
+ return;
+ }
+ SessionsChangedWrapper wrapper = new SessionsChangedWrapper(sessionListener, handler);
+ try {
+ mService.addSessionsListener(wrapper.mStub, notificationListener, userId);
+ mListeners.put(sessionListener, wrapper);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Error in addOnActiveSessionsChangedListener.", e);
+ }
}
}
@@ -184,14 +197,20 @@
*
* @param listener The listener to remove.
*/
- public void removeActiveSessionsListener(@NonNull SessionListener listener) {
+ public void removeOnActiveSessionsChangedListener(
+ @NonNull OnActiveSessionsChangedListener listener) {
if (listener == null) {
throw new IllegalArgumentException("listener may not be null");
}
- try {
- mService.removeSessionsListener(listener.mStub);
- } catch (RemoteException e) {
- Log.e(TAG, "Error in removeActiveSessionsListener.", e);
+ synchronized (mLock) {
+ SessionsChangedWrapper wrapper = mListeners.remove(listener);
+ if (wrapper != null) {
+ try {
+ mService.removeSessionsListener(wrapper.mStub);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Error in removeOnActiveSessionsChangedListener.", e);
+ }
+ }
}
}
@@ -257,28 +276,18 @@
/**
* Listens for changes to the list of active sessions. This can be added
- * using {@link #addActiveSessionsListener}.
+ * using {@link #addOnActiveSessionsChangedListener}.
*/
- public static abstract class SessionListener {
- private final Context mContext;
- private Handler mHandler;
+ public interface OnActiveSessionsChangedListener {
+ public void onActiveSessionsChanged(@Nullable List<MediaController> controllers);
+ }
- public SessionListener(Context context) {
- mContext = context;
- }
- /**
- * Called when the list of active sessions has changed. This can be due
- * to a session being added or removed or the order of sessions
- * changing. The controllers will be provided in priority order with the
- * most important controller at index 0.
- *
- * @param controllers The updated list of controllers for the user that
- * changed.
- */
- public abstract void onActiveSessionsChanged(
- @Nullable List<MediaController> controllers);
+ private final class SessionsChangedWrapper {
+ private final OnActiveSessionsChangedListener mListener;
+ private final Handler mHandler;
- private final void setHandler(Handler handler) {
+ public SessionsChangedWrapper(OnActiveSessionsChangedListener listener, Handler handler) {
+ mListener = listener;
mHandler = handler;
}
@@ -295,7 +304,7 @@
for (int i = 0; i < size; i++) {
controllers.add(new MediaController(mContext, tokens.get(i)));
}
- SessionListener.this.onActiveSessionsChanged(controllers);
+ mListener.onActiveSessionsChanged(controllers);
}
});
}
diff --git a/media/java/android/media/session/ParcelableVolumeInfo.java b/media/java/android/media/session/ParcelableVolumeInfo.java
index e71b539..96a45d9b 100644
--- a/media/java/android/media/session/ParcelableVolumeInfo.java
+++ b/media/java/android/media/session/ParcelableVolumeInfo.java
@@ -21,7 +21,7 @@
/**
* Convenience class for passing information about the audio configuration of a
- * session. The public implementation is {@link MediaController.VolumeInfo}.
+ * session. The public implementation is {@link MediaController.AudioInfo}.
*
* @hide
*/
diff --git a/media/java/android/media/session/PlaybackState.java b/media/java/android/media/session/PlaybackState.java
index 2ad8eae..566e218 100644
--- a/media/java/android/media/session/PlaybackState.java
+++ b/media/java/android/media/session/PlaybackState.java
@@ -120,11 +120,11 @@
public static final long ACTION_PLAY_FROM_SEARCH = 1 << 11;
/**
- * Indicates this performer supports the skip to track command.
+ * Indicates this performer supports the skip to item command.
*
* @see Builder#setActions(long)
*/
- public static final long ACTION_SKIP_TO_TRACK = 1 << 12;
+ public static final long ACTION_SKIP_TO_ITEM = 1 << 12;
/**
* This is the default playback state and indicates that no media has been
@@ -223,11 +223,11 @@
private List<PlaybackState.CustomAction> mCustomActions;
private final CharSequence mErrorMessage;
private final long mUpdateTime;
- private final long mActiveTrackId;
+ private final long mActiveItemId;
private PlaybackState(int state, long position, long updateTime, float speed,
long bufferPosition, long transportControls,
- List<PlaybackState.CustomAction> customActions, long activeTrackId,
+ List<PlaybackState.CustomAction> customActions, long activeItemId,
CharSequence error) {
mState = state;
mPosition = position;
@@ -236,7 +236,7 @@
mBufferPosition = bufferPosition;
mActions = transportControls;
mCustomActions = new ArrayList<>(customActions);
- mActiveTrackId = activeTrackId;
+ mActiveItemId = activeItemId;
mErrorMessage = error;
}
@@ -248,7 +248,7 @@
mBufferPosition = in.readLong();
mActions = in.readLong();
mCustomActions = in.createTypedArrayList(CustomAction.CREATOR);
- mActiveTrackId = in.readLong();
+ mActiveItemId = in.readLong();
mErrorMessage = in.readCharSequence();
}
@@ -263,7 +263,7 @@
bob.append(", updated=").append(mUpdateTime);
bob.append(", actions=").append(mActions);
bob.append(", custom actions=").append(mCustomActions);
- bob.append(", active track id=").append(mActiveTrackId);
+ bob.append(", active item id=").append(mActiveItemId);
bob.append(", error=").append(mErrorMessage);
bob.append("}");
return bob.toString();
@@ -283,7 +283,7 @@
dest.writeLong(mBufferPosition);
dest.writeLong(mActions);
dest.writeTypedList(mCustomActions);
- dest.writeLong(mActiveTrackId);
+ dest.writeLong(mActiveItemId);
dest.writeCharSequence(mErrorMessage);
}
@@ -716,7 +716,7 @@
private long mActions;
private CharSequence mErrorMessage;
private long mUpdateTime;
- private long mActiveTrackId = MediaSession.Track.UNKNOWN_ID;
+ private long mActiveItemId = MediaSession.Item.UNKNOWN_ID;
/**
* Creates an initially empty state builder.
@@ -744,14 +744,14 @@
}
mErrorMessage = from.mErrorMessage;
mUpdateTime = from.mUpdateTime;
- mActiveTrackId = from.mActiveTrackId;
+ mActiveItemId = from.mActiveItemId;
}
/**
* Set the current state of playback.
* <p>
* The position must be in ms and indicates the current playback
- * position within the track. If the position is unknown use
+ * position within the item. If the position is unknown use
* {@link #PLAYBACK_POSITION_UNKNOWN}. When not using an unknown
* position the time at which the position was updated must be provided.
* It is okay to use {@link SystemClock#elapsedRealtime()} if the
@@ -773,7 +773,7 @@
* </ul>
*
* @param state The current state of playback.
- * @param position The position in the current track in ms.
+ * @param position The position in the current item in ms.
* @param playbackSpeed The current speed of playback as a multiple of
* normal playback.
* @param updateTime The time in the {@link SystemClock#elapsedRealtime}
@@ -792,7 +792,7 @@
* Set the current state of playback.
* <p>
* The position must be in ms and indicates the current playback
- * position within the track. If the position is unknown use
+ * position within the item. If the position is unknown use
* {@link #PLAYBACK_POSITION_UNKNOWN}. The update time will be set to
* the current {@link SystemClock#elapsedRealtime()}.
* <p>
@@ -812,7 +812,7 @@
* </ul>
*
* @param state The current state of playback.
- * @param position The position in the current track in ms.
+ * @param position The position in the current item in ms.
* @param playbackSpeed The current speed of playback as a multiple of
* normal playback.
* @return this
@@ -902,14 +902,14 @@
}
/**
- * Set the active track in the play queue by specifying its id.
- * The default value is {@link MediaSession.Track#UNKNOWN_ID}
+ * Set the active item in the play queue by specifying its id. The
+ * default value is {@link MediaSession.Item#UNKNOWN_ID}
*
- * @param id The id of the active track.
+ * @param id The id of the active item.
* @return this
*/
- public Builder setActiveTrack(long id) {
- mActiveTrackId = id;
+ public Builder setActiveItem(long id) {
+ mActiveItemId = id;
return this;
}
@@ -932,7 +932,7 @@
*/
public PlaybackState build() {
return new PlaybackState(mState, mPosition, mUpdateTime, mSpeed, mBufferPosition,
- mActions, mCustomActions, mActiveTrackId, mErrorMessage);
+ mActions, mCustomActions, mActiveItemId, mErrorMessage);
}
}
}
diff --git a/media/java/android/media/tv/ITvInputSession.aidl b/media/java/android/media/tv/ITvInputSession.aidl
index 99fb911..1aad2fa 100644
--- a/media/java/android/media/tv/ITvInputSession.aidl
+++ b/media/java/android/media/tv/ITvInputSession.aidl
@@ -29,7 +29,7 @@
oneway interface ITvInputSession {
void release();
- void setMainSession(boolean isMainSession);
+ void setMain(boolean isMain);
void setSurface(in Surface surface);
void dispatchSurfaceChanged(int format, int width, int height);
// TODO: Remove this once it becomes irrelevant for applications to handle audio focus. The plan
diff --git a/media/java/android/media/tv/ITvInputSessionWrapper.java b/media/java/android/media/tv/ITvInputSessionWrapper.java
index 5022cc1..58e46f0 100644
--- a/media/java/android/media/tv/ITvInputSessionWrapper.java
+++ b/media/java/android/media/tv/ITvInputSessionWrapper.java
@@ -42,7 +42,7 @@
private static final String TAG = "TvInputSessionWrapper";
private static final int DO_RELEASE = 1;
- private static final int DO_SET_MAIN_SESSION = 2;
+ private static final int DO_SET_MAIN = 2;
private static final int DO_SET_SURFACE = 3;
private static final int DO_DISPATCH_SURFACE_CHANGED = 4;
private static final int DO_SET_STREAM_VOLUME = 5;
@@ -91,8 +91,8 @@
}
return;
}
- case DO_SET_MAIN_SESSION: {
- mTvInputSessionImpl.setMainSession((Boolean) msg.obj);
+ case DO_SET_MAIN: {
+ mTvInputSessionImpl.setMain((Boolean) msg.obj);
return;
}
case DO_SET_SURFACE: {
@@ -162,8 +162,8 @@
}
@Override
- public void setMainSession(boolean isMain) {
- mCaller.executeOrSendMessage(mCaller.obtainMessageO(DO_SET_MAIN_SESSION, isMain));
+ public void setMain(boolean isMain) {
+ mCaller.executeOrSendMessage(mCaller.obtainMessageO(DO_SET_MAIN, isMain));
}
@Override
diff --git a/media/java/android/media/tv/TvInputManager.java b/media/java/android/media/tv/TvInputManager.java
index f76c78b..45aa6d6 100644
--- a/media/java/android/media/tv/TvInputManager.java
+++ b/media/java/android/media/tv/TvInputManager.java
@@ -1023,10 +1023,12 @@
}
/**
- * Sets this as main session. See {@link TvView#setMainTvView} for about meaning of "main".
- * @hide
+ * Sets this as the main session. The main session is a session whose corresponding TV
+ * input determines the HDMI-CEC active source device.
+ *
+ * @see TvView#setMain
*/
- public void setMainSession() {
+ void setMain() {
if (mToken == null) {
Log.w(TAG, "The session has been already released");
return;
@@ -1339,6 +1341,9 @@
Log.w(TAG, "The session has been already released");
return;
}
+ if (unblockedRating == null) {
+ throw new IllegalArgumentException("unblockedRating cannot be null");
+ }
try {
mService.requestUnblockContent(mToken, unblockedRating.flattenToString(), mUserId);
} catch (RemoteException e) {
diff --git a/media/java/android/media/tv/TvInputService.java b/media/java/android/media/tv/TvInputService.java
index c93b261..e3292b6 100644
--- a/media/java/android/media/tv/TvInputService.java
+++ b/media/java/android/media/tv/TvInputService.java
@@ -94,6 +94,8 @@
private final RemoteCallbackList<ITvInputServiceCallback> mCallbacks =
new RemoteCallbackList<ITvInputServiceCallback>();
+ private TvInputManager mTvInputManager;
+
@Override
public final IBinder onBind(Intent intent) {
return new ITvInputService.Stub() {
@@ -225,6 +227,17 @@
return null;
}
+ private boolean isPassthroughInput(String inputId) {
+ if (mTvInputManager == null) {
+ mTvInputManager = (TvInputManager) getSystemService(Context.TV_INPUT_SERVICE);
+ }
+ TvInputInfo info = mTvInputManager.getTvInputInfo(inputId);
+ if (info != null && info.isPassthroughInput()) {
+ return true;
+ }
+ return false;
+ }
+
/**
* Base class for derived classes to implement to provide a TV input session.
*/
@@ -538,29 +551,30 @@
public abstract void onRelease();
/**
- * Set the current session as the "main" session. See {@link TvView#setMainTvView} for the
- * meaning of "main".
+ * Sets the current session as the main session. The main session is a session whose
+ * corresponding TV input determines the HDMI-CEC active source device.
* <p>
- * This is primarily for HDMI-CEC active source management. TV input service that manages
- * HDMI-CEC logical device should make sure not only to select the corresponding HDMI
- * logical device as source device on {@code onSetMainSession(true)}, but also to select
- * internal device on {@code onSetMainSession(false)}. Also, if surface is set to non-main
- * session, it needs to select internal device after temporarily selecting corresponding
- * HDMI logical device for set up.
+ * TV input service that manages HDMI-CEC logical device should implement {@link
+ * #onSetMain} to (1) select the corresponding HDMI logical device as the source device
+ * when {@code isMain} is {@code true}, and to (2) select the internal device (= TV itself)
+ * as the source device when {@code isMain} is {@code false} and the session is still main.
+ * Also, if a surface is passed to a non-main session and active source is changed to
+ * initiate the surface, the active source should be returned to the main session.
* </p><p>
- * It is guaranteed that {@code onSetMainSession(true)} for new session is called first,
- * and {@code onSetMainSession(false)} for old session is called afterwards. This allows
- * {@code onSetMainSession(false)} to be no-op when TV input service knows that the next
- * main session corresponds to another HDMI logical device. Practically, this implies that
- * one TV input service should handle all HDMI port and HDMI-CEC logical devices for smooth
- * active source transition.
+ * {@link TvView} guarantees that, when tuning involves a session transition, {@code
+ * onSetMain(true)} for new session is called first, {@code onSetMain(false)} for old
+ * session is called afterwards. This allows {@code onSetMain(false)} to be no-op when TV
+ * input service knows that the next main session corresponds to another HDMI logical
+ * device. Practically, this implies that one TV input service should handle all HDMI port
+ * and HDMI-CEC logical devices for smooth active source transition.
* </p>
*
- * @param isMainSession If true, session is main.
+ * @param isMain If true, session should become main.
+ * @see TvView#setMain
* @hide
*/
@SystemApi
- public void onSetMainSession(boolean isMainSession) {
+ public void onSetMain(boolean isMain) {
}
/**
@@ -828,10 +842,10 @@
}
/**
- * Calls {@link #onSetMainSession}.
+ * Calls {@link #onSetMain}.
*/
- void setMainSession(boolean isMainSession) {
- onSetMainSession(isMainSession);
+ void setMain(boolean isMain) {
+ onSetMain(isMain);
}
/**
@@ -1229,9 +1243,14 @@
HardwareSession proxySession =
((HardwareSession) sessionImpl);
String harewareInputId = proxySession.getHardwareInputId();
- if (TextUtils.isEmpty(harewareInputId)) {
+ if (TextUtils.isEmpty(harewareInputId) ||
+ !isPassthroughInput(harewareInputId)) {
+ if (TextUtils.isEmpty(harewareInputId)) {
+ Log.w(TAG, "Hardware input id is not setup yet.");
+ } else {
+ Log.w(TAG, "Invalid hardware input id : " + harewareInputId);
+ }
sessionImpl.onRelease();
- Log.w(TAG, "Hardware input id is not setup yet.");
try {
cb.onSessionCreated(null, null);
} catch (RemoteException e) {
@@ -1239,7 +1258,6 @@
}
return;
}
- // TODO: check if the given ID is really hardware TV input.
proxySession.mProxySession = stub;
proxySession.mProxySessionCallback = cb;
proxySession.mServiceHandler = mServiceHandler;
diff --git a/media/java/android/media/tv/TvView.java b/media/java/android/media/tv/TvView.java
index 591f543..445194e 100644
--- a/media/java/android/media/tv/TvView.java
+++ b/media/java/android/media/tv/TvView.java
@@ -116,8 +116,10 @@
private final SurfaceHolder.Callback mSurfaceHolderCallback = new SurfaceHolder.Callback() {
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
- Log.d(TAG, "surfaceChanged(holder=" + holder + ", format=" + format + ", width=" + width
- + ", height=" + height + ")");
+ if (DEBUG) {
+ Log.d(TAG, "surfaceChanged(holder=" + holder + ", format=" + format + ", width="
+ + width + ", height=" + height + ")");
+ }
mSurfaceFormat = format;
mSurfaceWidth = width;
mSurfaceHeight = height;
@@ -188,24 +190,27 @@
}
/**
- * Sets this as main TvView.
+ * Sets this as the main {@link TvView}.
* <p>
- * Main TvView is the TvView which user is watching and interacting mainly. It is used for
- * determining internal behavior of hardware TV input devices. For example, this influences
- * how HDMI-CEC active source will be managed.
+ * The main {@link TvView} is a {@link TvView} whose corresponding TV input determines the
+ * HDMI-CEC active source device. For an HDMI port input, one of source devices that is
+ * connected to that HDMI port becomes the active source. For an HDMI-CEC logical device input,
+ * the corresponding HDMI-CEC logical device becomes the active source. For any non-HDMI input
+ * (including the tuner, composite, S-Video, etc.), the internal device (= TV itself) becomes
+ * the active source.
* </p><p>
- * First tuned TvView becomes main automatically, and keeps to be main until setMainTvView() is
- * called for other TvView. Note that main TvView won't be reset even when current main TvView
- * is removed from view hierarchy.
+ * First tuned {@link TvView} becomes main automatically, and keeps to be main until {@link
+ * #setMain} is called for other {@link TvView}. Note that main {@link TvView} won't be reset
+ * even when current main {@link TvView} is removed from view hierarchy.
* </p>
* @hide
*/
@SystemApi
- public void setMainTvView() {
+ public void setMain() {
synchronized (sMainTvViewLock) {
sMainTvView = this;
if (hasWindowFocus() && mSession != null) {
- mSession.setMainSession();
+ mSession.setMain();
}
}
}
@@ -327,6 +332,7 @@
* This method is primarily used to un-tune the current TvView.
*/
public void reset() {
+ if (DEBUG) Log.d(TAG, "reset()");
if (mSession != null) {
release();
resetSurfaceView();
@@ -538,7 +544,7 @@
// Set main again to regain main session.
synchronized (sMainTvViewLock) {
if (hasFocus && this == sMainTvView && mSession != null) {
- mSession.setMainSession();
+ mSession.setMain();
}
}
}
@@ -596,6 +602,7 @@
mSurfaceView.getHolder().removeCallback(mSurfaceHolderCallback);
removeView(mSurfaceView);
}
+ mSurface = null;
mSurfaceView = new SurfaceView(getContext(), mAttrs, mDefStyleAttr) {
@Override
protected void updateWindow(boolean force, boolean redrawNeeded) {
@@ -821,11 +828,14 @@
}
return;
}
+ if (DEBUG) {
+ Log.d(TAG, "onSessionCreated()");
+ }
mSession = session;
if (session != null) {
synchronized (sMainTvViewLock) {
if (hasWindowFocus() && TvView.this == sMainTvView) {
- mSession.setMainSession();
+ mSession.setMain();
}
}
// mSurface may not be ready yet as soon as starting an application.
diff --git a/packages/Shell/AndroidManifest.xml b/packages/Shell/AndroidManifest.xml
index 6f41565..f1d2bee3 100644
--- a/packages/Shell/AndroidManifest.xml
+++ b/packages/Shell/AndroidManifest.xml
@@ -90,6 +90,7 @@
<uses-permission android:name="android.permission.RETRIEVE_WINDOW_TOKEN" />
<uses-permission android:name="android.permission.FRAME_STATS" />
<uses-permission android:name="android.permission.BIND_APPWIDGET" />
+ <uses-permission android:name="android.permission.UPDATE_APP_OPS_STATS" />
<application android:label="@string/app_label">
<provider
diff --git a/packages/SystemUI/res/drawable/ic_qs_bugreport.xml b/packages/SystemUI/res/drawable/ic_qs_bugreport.xml
deleted file mode 100644
index 0df1a96..0000000
--- a/packages/SystemUI/res/drawable/ic_qs_bugreport.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<!--
-Copyright (C) 2014 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="64dp"
- android:height="64dp"
- android:viewportWidth="24.0"
- android:viewportHeight="24.0">
-
- <path
- android:fillColor="#FFFFFFFF"
- android:pathData="M20.0,8.0l-2.8,0.0c-0.5,-0.8 -1.1,-1.5 -1.8,-2.0L17.0,4.4L15.6,3.0l-2.2,2.2C13.0,5.1 12.5,5.0 12.0,5.0s-1.0,0.1 -1.4,0.2L8.4,3.0L7.0,4.4L8.6,6.0C7.9,6.5 7.3,7.2 6.8,8.0L4.0,8.0l0.0,2.0l2.1,0.0C6.0,10.3 6.0,10.7 6.0,11.0l0.0,1.0L4.0,12.0l0.0,2.0l2.0,0.0l0.0,1.0c0.0,0.3 0.0,0.7 0.1,1.0L4.0,16.0l0.0,2.0l2.8,0.0c1.0,1.8 3.0,3.0 5.2,3.0s4.2,-1.2 5.2,-3.0L20.0,18.0l0.0,-2.0l-2.1,0.0c0.1,-0.3 0.1,-0.7 0.1,-1.0l0.0,-1.0l2.0,0.0l0.0,-2.0l-2.0,0.0l0.0,-1.0c0.0,-0.3 0.0,-0.7 -0.1,-1.0L20.0,10.0L20.0,8.0zM14.0,16.0l-4.0,0.0l0.0,-2.0l4.0,0.0L14.0,16.0zM14.0,12.0l-4.0,0.0l0.0,-2.0l4.0,0.0L14.0,12.0z"/>
-</vector>
diff --git a/packages/SystemUI/res/layout/keyguard_status_bar.xml b/packages/SystemUI/res/layout/keyguard_status_bar.xml
index fcc0f4a..faa2820 100644
--- a/packages/SystemUI/res/layout/keyguard_status_bar.xml
+++ b/packages/SystemUI/res/layout/keyguard_status_bar.xml
@@ -60,7 +60,8 @@
android:paddingEnd="@dimen/battery_level_padding_end"
android:textColor="#ffffff"
android:visibility="gone"
- android:textSize="@dimen/battery_level_text_size"/>
+ android:textSize="@dimen/battery_level_text_size"
+ android:importantForAccessibility="noHideDescendants"/>
</LinearLayout>
<com.android.keyguard.CarrierText
diff --git a/packages/SystemUI/res/layout/recents_task_view.xml b/packages/SystemUI/res/layout/recents_task_view.xml
index 828065b..5253ee0 100644
--- a/packages/SystemUI/res/layout/recents_task_view.xml
+++ b/packages/SystemUI/res/layout/recents_task_view.xml
@@ -69,6 +69,7 @@
android:layout_gravity="bottom|right"
android:layout_marginRight="15dp"
android:layout_marginBottom="15dp"
+ android:translationZ="3dp"
android:contentDescription="@string/recents_lock_to_app_button_label"
android:background="@drawable/recents_lock_to_task_button_bg">
<ImageView
diff --git a/packages/SystemUI/res/layout/status_bar_expanded_header.xml b/packages/SystemUI/res/layout/status_bar_expanded_header.xml
index 079b97b..aa276bc 100644
--- a/packages/SystemUI/res/layout/status_bar_expanded_header.xml
+++ b/packages/SystemUI/res/layout/status_bar_expanded_header.xml
@@ -72,7 +72,8 @@
android:layout_marginStart="@dimen/header_battery_margin_expanded"
android:paddingEnd="@dimen/battery_level_padding_end"
android:textColor="#ffffff"
- android:textSize="@dimen/battery_level_text_size"/>
+ android:textSize="@dimen/battery_level_text_size"
+ android:importantForAccessibility="noHideDescendants"/>
</LinearLayout>
<TextView
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index 5415d19..1b8eeb2 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -205,10 +205,10 @@
<dimen name="recents_task_view_rounded_corners_radius">2dp</dimen>
<!-- The min translation in the Z index for the last task. -->
- <dimen name="recents_task_view_z_min">5dp</dimen>
+ <dimen name="recents_task_view_z_min">25dp</dimen>
<!-- The max translation in the Z index for the last task. -->
- <dimen name="recents_task_view_z_max">65dp</dimen>
+ <dimen name="recents_task_view_z_max">100dp</dimen>
<!-- The amount to translate when animating the removal of a task. -->
<dimen name="recents_task_view_remove_anim_translation_x">100dp</dimen>
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index d145172..d49312d 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -273,6 +273,13 @@
<!-- Content description of the WIFI signal when it is full for accessibility (not shown on the screen). [CHAR LIMIT=NONE] -->
<string name="accessibility_wifi_signal_full">Wifi signal full.</string>
+ <!-- Content description of the wifi label showing what we are connected to. [CHAR LIMIT=NONE] -->
+ <string name="accessibility_wifi_name">Connected to <xliff:g id="wifi" example="Home Network">%s</xliff:g>.</string>
+
+ <!-- Content description of the bluetooth label showing what we are connected to. [CHAR LIMIT=NONE] -->
+ <string name="accessibility_bluetooth_name">Connected to <xliff:g id="bluetooth" example="Car Audio">%s</xliff:g>.</string>
+
+
<!-- Content description of the WiMAX signal when no signal for accessibility (not shown on the screen). [CHAR LIMIT=NONE] -->
<string name="accessibility_no_wimax">No WiMAX.</string>
<!-- Content description of the WiMAX signal when it is one bar for accessibility (not shown on the screen). [CHAR LIMIT=NONE] -->
@@ -390,6 +397,8 @@
<string name="accessibility_desc_notification_shade">Notification shade.</string>
<!-- Content description for the quick settings panel (not shown on the screen). [CHAR LIMIT=NONE] -->
<string name="accessibility_desc_quick_settings">Quick settings.</string>
+ <!-- Content description for the lock screen (not shown on the screen). [CHAR LIMIT=NONE] -->
+ <string name="accessibility_desc_lock_screen">Lock screen.</string>
<!-- Content description for the settings button in the status bar header. [CHAR LIMIT=NONE] -->
<string name="accessibility_desc_settings">Settings</string>
<!-- Content description for the recent apps panel (not shown on the screen). [CHAR LIMIT=NONE] -->
@@ -398,7 +407,7 @@
<!-- Content description of the user tile in quick settings (not shown on the screen). [CHAR LIMIT=NONE] -->
<string name="accessibility_quick_settings_user">User <xliff:g id="user" example="John Doe">%s</xliff:g>.</string>
<!-- Content description of the wifi tile in quick settings (not shown on the screen). [CHAR LIMIT=NONE] -->
- <string name="accessibility_quick_settings_wifi"><xliff:g id="signal" example="Three bars">%1$s</xliff:g>. <xliff:g id="network" example="MyWifiNetwork">%2$s</xliff:g></string>
+ <string name="accessibility_quick_settings_wifi"><xliff:g id="signal" example="Three bars">%1$s</xliff:g>.</string>
<!-- Content description of the mobile data tile in quick settings (not shown on the screen). [CHAR LIMIT=NONE] -->
<string name="accessibility_quick_settings_mobile">Mobile <xliff:g id="signal" example="Three bars">%1$s</xliff:g>. <xliff:g id="type" example="4G">%2$s</xliff:g>. <xliff:g id="network" example="T-Mobile">%3$s</xliff:g>.</string>
<!-- Content description of the battery tile in quick settings (not shown on the screen). [CHAR LIMIT=NONE] -->
@@ -577,7 +586,7 @@
<!-- QuickSettings: Cellular detail panel, remaining data title [CHAR LIMIT=NONE] -->
<string name="quick_settings_cellular_detail_remaining_data">Remaining data</string>
<!-- QuickSettings: Cellular detail panel, over limit title [CHAR LIMIT=NONE] -->
- <string name="quick_settings_cellular_detail_over_limit">Over limit</string>
+ <string name="quick_settings_cellular_detail_over_limit">Limit reached – data usage paused</string>
<!-- QuickSettings: Cellular detail panel, data used format string [CHAR LIMIT=NONE] -->
<string name="quick_settings_cellular_detail_data_used"><xliff:g id="data_used" example="2.0 GB">%s</xliff:g> used</string>
<!-- QuickSettings: Cellular detail panel, data limit format string [CHAR LIMIT=NONE] -->
@@ -659,8 +668,6 @@
<!-- Shows when people have clicked at the right edge of the screen to explain how to open the phone. In right-to-left languages, this is the opposite direction. [CHAR LIMIT=60] -->
<string name="camera_hint">Swipe left for camera</string>
- <string name="bugreport_tile_extended" translatable="false">%s\n%s (%s)</string>
-
<!-- Zen mode condition: no exit criteria. [CHAR LIMIT=NONE] -->
<string name="zen_mode_forever">Indefinitely</string>
@@ -700,10 +707,13 @@
<string name="guest_exit_guest">Remove guest</string>
<!-- Title of the confirmation dialog when exiting guest session [CHAR LIMIT=NONE] -->
- <string name="guest_exit_guest_dialog_title">Exiting guest session?</string>
+ <string name="guest_exit_guest_dialog_title">Remove guest?</string>
<!-- Message of the confirmation dialog when exiting guest session [CHAR LIMIT=NONE] -->
- <string name="guest_exit_guest_dialog_message">Exiting the guest session will remove local data.</string>
+ <string name="guest_exit_guest_dialog_message">All apps and data in this session will be deleted.</string>
+
+ <!-- Label for button in confirmation dialog when exiting guest session [CHAR LIMIT=35] -->
+ <string name="guest_exit_guest_dialog_remove">Remove</string>
<!-- Title of the notification when resuming an existing guest session [CHAR LIMIT=NONE] -->
<string name="guest_wipe_session_title">Welcome back, guest!</string>
diff --git a/packages/SystemUI/res/values/styles.xml b/packages/SystemUI/res/values/styles.xml
index 27e58a4..48a031a 100644
--- a/packages/SystemUI/res/values/styles.xml
+++ b/packages/SystemUI/res/values/styles.xml
@@ -21,11 +21,23 @@
</style>
<!-- Alternate Recents theme -->
- <style name="RecentsTheme" parent="@android:style/Theme.DeviceDefault.Wallpaper.NoTitleBar">
+ <style name="RecentsTheme" parent="@android:style/Theme">
+ <!-- NoTitle -->
+ <item name="android:windowNoTitle">true</item>
+ <!-- Wallpaper -->
+ <item name="android:windowBackground">@color/transparent</item>
+ <item name="android:colorBackgroundCacheHint">@null</item>
+ <item name="android:windowShowWallpaper">true</item>
+ <!-- Misc -->
<item name="android:statusBarColor">@android:color/transparent</item>
<item name="android:navigationBarColor">@android:color/transparent</item>
<item name="android:windowDrawsSystemBarBackgrounds">true</item>
<item name="android:windowAnimationStyle">@style/Animation.RecentsActivity</item>
+ <item name="*android:lightingStyle">@style/RecentsLighting</item>
+ </style>
+
+ <style name="RecentsLighting" parent="@*android:style/Lighting">
+ <item name="*android:ambientShadowAlpha">0.30</item>
</style>
<!-- Animations for a non-full-screen window or activity. -->
diff --git a/packages/SystemUI/src/com/android/systemui/net/NetworkOverLimitActivity.java b/packages/SystemUI/src/com/android/systemui/net/NetworkOverLimitActivity.java
index fe7aa75..b3c0783 100644
--- a/packages/SystemUI/src/com/android/systemui/net/NetworkOverLimitActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/net/NetworkOverLimitActivity.java
@@ -33,6 +33,7 @@
import android.os.RemoteException;
import android.os.ServiceManager;
import android.util.Log;
+import android.view.WindowManager;
import com.android.systemui.R;
@@ -62,6 +63,7 @@
});
final Dialog dialog = builder.create();
+ dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
dialog.setOnDismissListener(new DialogInterface.OnDismissListener() {
public void onDismiss(DialogInterface dialog) {
finish();
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
index 1fa97bd..bf01b7b 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
@@ -347,8 +347,8 @@
}
for (TileRecord record : mRecords) {
- if (record.tileView.getVisibility() == GONE) continue;
record.tileView.setDual(record.tile.supportsDualTargets());
+ if (record.tileView.getVisibility() == GONE) continue;
final int cw = record.row == 0 ? mLargeCellWidth : mCellWidth;
final int ch = record.row == 0 ? mLargeCellHeight : mCellHeight;
record.tileView.measure(exactly(cw), exactly(ch));
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSTile.java b/packages/SystemUI/src/com/android/systemui/qs/QSTile.java
index 6975541..409cc46 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSTile.java
@@ -286,6 +286,7 @@
public Drawable icon;
public String label;
public String contentDescription;
+ public String dualLabelContentDescription;
public boolean copyTo(State other) {
if (other == null) throw new IllegalArgumentException();
@@ -294,12 +295,15 @@
|| other.iconId != iconId
|| !Objects.equals(other.icon, icon)
|| !Objects.equals(other.label, label)
- || !Objects.equals(other.contentDescription, contentDescription);
+ || !Objects.equals(other.contentDescription, contentDescription)
+ || !Objects.equals(other.dualLabelContentDescription,
+ dualLabelContentDescription);
other.visible = visible;
other.iconId = iconId;
other.icon = icon;
other.label = label;
other.contentDescription = contentDescription;
+ other.dualLabelContentDescription = dualLabelContentDescription;
return changed;
}
@@ -315,6 +319,7 @@
sb.append(",icon=").append(icon);
sb.append(",label=").append(label);
sb.append(",contentDescription=").append(contentDescription);
+ sb.append(",dualLabelContentDescription=").append(dualLabelContentDescription);
return sb.append(']');
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSTileView.java b/packages/SystemUI/src/com/android/systemui/qs/QSTileView.java
index 597bb93..2cc1f07 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSTileView.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSTileView.java
@@ -87,6 +87,7 @@
private void recreateLabel() {
CharSequence labelText = null;
+ CharSequence labelDescription = null;
if (mLabel != null) {
labelText = mLabel.getText();
removeView(mLabel);
@@ -94,6 +95,7 @@
}
if (mDualLabel != null) {
labelText = mDualLabel.getText();
+ labelDescription = mLabel.getContentDescription();
removeView(mDualLabel);
mDualLabel = null;
}
@@ -113,6 +115,9 @@
if (labelText != null) {
mDualLabel.setText(labelText);
}
+ if (labelDescription != null) {
+ mDualLabel.setContentDescription(labelDescription);
+ }
addView(mDualLabel);
} else {
mLabel = new TextView(mContext);
@@ -228,6 +233,7 @@
}
if (mDual) {
mDualLabel.setText(state.label);
+ mDualLabel.setContentDescription(state.dualLabelContentDescription);
} else {
mLabel.setText(state.label);
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java
index 1b2c0b0..19b9ec1 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java
@@ -114,6 +114,12 @@
}
state.contentDescription = mContext.getString(
R.string.accessibility_quick_settings_bluetooth, stateContentDescription);
+ String bluetoothName = state.label;
+ if (connected) {
+ bluetoothName = state.dualLabelContentDescription = mContext.getString(
+ R.string.accessibility_bluetooth_name, state.label);
+ }
+ state.dualLabelContentDescription = bluetoothName;
}
private final BluetoothController.Callback mCallback = new BluetoothController.Callback() {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/BugreportTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/BugreportTile.java
deleted file mode 100644
index a308e84..0000000
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/BugreportTile.java
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.qs.tiles;
-
-import android.app.ActivityManagerNative;
-import android.app.AlertDialog;
-import android.app.Dialog;
-import android.content.DialogInterface;
-import android.content.DialogInterface.OnClickListener;
-import android.os.Build;
-import android.os.RemoteException;
-import android.provider.Settings.Global;
-import android.view.WindowManager;
-import android.view.WindowManagerGlobal;
-
-import com.android.systemui.R;
-import com.android.systemui.qs.GlobalSetting;
-import com.android.systemui.qs.QSTile;
-
-/** Quick settings tile: Bug report **/
-public class BugreportTile extends QSTile<QSTile.State> {
-
- private final GlobalSetting mSetting;
-
- public BugreportTile(Host host) {
- super(host);
- mSetting = new GlobalSetting(mContext, mHandler, Global.BUGREPORT_IN_POWER_MENU) {
- @Override
- protected void handleValueChanged(int value) {
- handleRefreshState(null);
- }
- };
- }
-
- @Override
- protected State newTileState() {
- return new State();
- }
-
- @Override
- public void setListening(boolean listening) {
- mSetting.setListening(listening);
- }
-
- @Override
- protected void handleClick() {
- mHandler.post(new Runnable() {
- @Override
- public void run() {
- mHost.collapsePanels();
- mUiHandler.post(mShowDialog);
- }
- });
- }
-
- @Override
- protected void handleUpdateState(State state, Object pushArg) {
- state.visible = mSetting.getValue() != 0;
- state.iconId = R.drawable.ic_qs_bugreport;
- state.label = mContext.getString(
- R.string.bugreport_tile_extended,
- mContext.getString(com.android.internal.R.string.bugreport_title),
- Build.VERSION.RELEASE,
- Build.ID);
- }
-
- private final Runnable mShowDialog = new Runnable() {
- @Override
- public void run() {
- final AlertDialog.Builder builder = new AlertDialog.Builder(mContext);
- builder.setPositiveButton(com.android.internal.R.string.report, new OnClickListener() {
- @Override
- public void onClick(DialogInterface dialog, int which) {
- if (which == DialogInterface.BUTTON_POSITIVE) {
- // Add a little delay before executing, to give the
- // dialog a chance to go away before it takes a
- // screenshot.
- mHandler.postDelayed(new Runnable() {
- @Override public void run() {
- try {
- ActivityManagerNative.getDefault().requestBugReport();
- } catch (RemoteException e) {
- }
- }
- }, 500);
- }
- }
- });
- builder.setMessage(com.android.internal.R.string.bugreport_message);
- builder.setTitle(com.android.internal.R.string.bugreport_title);
- builder.setCancelable(true);
- final Dialog dialog = builder.create();
- dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
- try {
- WindowManagerGlobal.getWindowManagerService().dismissKeyguard();
- } catch (RemoteException e) {
- }
- dialog.show();
- }
- };
-}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/ColorInversionTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/ColorInversionTile.java
index 21254d4..edb5932 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/ColorInversionTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/ColorInversionTile.java
@@ -29,6 +29,8 @@
private final SecureSetting mSetting;
private final UsageTracker mUsageTracker;
+ private boolean mListening;
+
public ColorInversionTile(Host host) {
super(host);
@@ -36,18 +38,25 @@
Secure.ACCESSIBILITY_DISPLAY_INVERSION_ENABLED) {
@Override
protected void handleValueChanged(int value) {
- handleRefreshState(value);
mUsageTracker.trackUsage();
+ if (mListening) {
+ handleRefreshState(value);
+ }
}
};
mUsageTracker = new UsageTracker(host.getContext(), ColorInversionTile.class);
+ if (mSetting.getValue() != 0 && !mUsageTracker.isRecentlyUsed()) {
+ mUsageTracker.trackUsage();
+ }
mUsageTracker.setListening(true);
+ mSetting.setListening(true);
}
@Override
protected void handleDestroy() {
super.handleDestroy();
mUsageTracker.setListening(false);
+ mSetting.setListening(false);
}
@Override
@@ -57,7 +66,7 @@
@Override
public void setListening(boolean listening) {
- mSetting.setListening(listening);
+ mListening = listening;
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java
index 5651d49..a8bf026 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java
@@ -132,8 +132,12 @@
}
state.contentDescription = mContext.getString(
R.string.accessibility_quick_settings_wifi,
- signalContentDescription,
- state.connected ? state.label : "");
+ signalContentDescription);
+ String wifiName = state.label;
+ if (state.connected) {
+ wifiName = r.getString(R.string.accessibility_wifi_name, state.label);
+ }
+ state.dualLabelContentDescription = wifiName;
}
private static String removeDoubleQuotes(String string) {
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewLayoutAlgorithm.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewLayoutAlgorithm.java
index 667faa7..f0bdfa2 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewLayoutAlgorithm.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewLayoutAlgorithm.java
@@ -53,7 +53,7 @@
// Log function
static final float XScale = 1.75f; // The large the XScale, the longer the flat area of the curve
- static final float LogBase = 300;
+ static final float LogBase = 3000;
static final int PrecisionSteps = 250;
static float[] xp;
static float[] px;
@@ -84,7 +84,7 @@
left + size, mStackRect.top + size);
// Update the affiliation offsets
- float visibleTaskPct = 0.55f;
+ float visibleTaskPct = 0.5f;
mWithinAffiliationOffset = mConfig.taskBarHeight;
mBetweenAffiliationOffset = (int) (visibleTaskPct * mTaskRect.height());
}
@@ -312,4 +312,4 @@
}
return px[xFloorIndex] + pFraction;
}
-}
\ No newline at end of file
+}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java
index 5914b39..e514c90 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java
@@ -21,12 +21,14 @@
import android.animation.ValueAnimator;
import android.content.Context;
import android.graphics.Color;
+import android.graphics.Outline;
import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffColorFilter;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.view.View;
+import android.view.ViewOutlineProvider;
import android.view.animation.AccelerateInterpolator;
import android.widget.FrameLayout;
import com.android.systemui.R;
@@ -57,7 +59,7 @@
ObjectAnimator mDimAnimator;
float mMaxDimScale;
int mDim;
- AccelerateInterpolator mDimInterpolator = new AccelerateInterpolator(1.25f);
+ AccelerateInterpolator mDimInterpolator = new AccelerateInterpolator(1f);
PorterDuffColorFilter mDimColorFilter = new PorterDuffColorFilter(0, PorterDuff.Mode.MULTIPLY);
Task mTask;
@@ -129,6 +131,14 @@
mHeaderView = (TaskViewHeader) findViewById(R.id.task_view_bar);
mThumbnailView = (TaskViewThumbnail) findViewById(R.id.task_view_thumbnail);
mActionButtonView = findViewById(R.id.lock_to_app_fab);
+ mActionButtonView.setOutlineProvider(new ViewOutlineProvider() {
+ @Override
+ public void getOutline(View view, Outline outline) {
+ // Set the outline to match the FAB background
+ outline.setOval(0, 0, mActionButtonView.getWidth(),
+ mActionButtonView.getHeight());
+ }
+ });
if (mFooterView != null) {
mFooterView.setCallbacks(this);
}
@@ -469,7 +479,8 @@
boolean occludesLaunchTarget) {
if (isLaunchingTask) {
// Disable the thumbnail clip and animate the bar out for the window animation out
- mHeaderView.startLaunchTaskAnimation(mThumbnailView.disableTaskBarClipAsRunnable(), r);
+ mHeaderView.startLaunchTaskAnimation(mThumbnailView.disableTaskBarClipAsRunnable(), r,
+ mIsFocused);
// Animate the thumbnail alpha back into full opacity for the window animation out
mThumbnailView.startLaunchTaskAnimation();
@@ -624,7 +635,7 @@
public void setDim(int dim) {
mDim = dim;
// Defer setting hardware layers if we have not yet measured, or there is no dim to draw
- if (getMeasuredWidth() > 0 && getMeasuredHeight() > 0 && dim > 0) {
+ if (getMeasuredWidth() > 0 && getMeasuredHeight() > 0) {
if (mDimAnimator != null) {
mDimAnimator.removeAllListeners();
mDimAnimator.cancel();
@@ -828,6 +839,10 @@
} else if (v == mHeaderView.mDismissButton) {
dismissTask();
} else {
+ if (v == mActionButtonView) {
+ // Reset the translation of the action button before we animate it out
+ mActionButtonView.setTranslationZ(0f);
+ }
mCb.onTaskViewClicked(tv, tv.getTask(),
(v == mFooterView || v == mActionButtonView));
}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewHeader.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewHeader.java
index 4b09549..c7198fe 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewHeader.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewHeader.java
@@ -18,7 +18,9 @@
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
+import android.animation.AnimatorSet;
import android.animation.ArgbEvaluator;
+import android.animation.ObjectAnimator;
import android.animation.ValueAnimator;
import android.content.Context;
import android.content.res.ColorStateList;
@@ -59,7 +61,8 @@
ColorDrawable mBackgroundColor;
Drawable mLightDismissDrawable;
Drawable mDarkDismissDrawable;
- ValueAnimator mBackgroundColorAnimator;
+ AnimatorSet mFocusAnimator;
+ ValueAnimator backgroundColorAnimator;
boolean mIsFullscreen;
boolean mCurrentPrimaryColorIsDark;
@@ -117,6 +120,14 @@
@Override
protected void onFinishInflate() {
+ // Set the outline provider
+ setOutlineProvider(new ViewOutlineProvider() {
+ @Override
+ public void getOutline(View view, Outline outline) {
+ outline.setRect(0, 0, getMeasuredWidth(), getMeasuredHeight());
+ }
+ });
+
// Initialize the icon and description views
mApplicationIcon = (ImageView) findViewById(R.id.application_icon);
mActivityDescription = (TextView) findViewById(R.id.activity_description);
@@ -211,23 +222,29 @@
void startEnterRecentsAnimation(int delay, Runnable postAnimRunnable) {
// Animate the task bar of the first task view
setVisibility(View.VISIBLE);
- setTranslationY(-getMeasuredHeight());
+ setAlpha(0f);
animate()
- .translationY(0)
+ .alpha(1f)
.setStartDelay(delay)
- .setInterpolator(mConfig.fastOutSlowInInterpolator)
+ .setInterpolator(mConfig.linearOutSlowInInterpolator)
.setDuration(mConfig.taskBarEnterAnimDuration)
.withEndAction(postAnimRunnable)
+ .withLayer()
.start();
}
/** Animates this task bar as it exits recents */
- void startLaunchTaskAnimation(Runnable preAnimRunnable, final Runnable postAnimRunnable) {
+ void startLaunchTaskAnimation(Runnable preAnimRunnable, final Runnable postAnimRunnable,
+ boolean isFocused) {
+ if (isFocused) {
+ onTaskViewFocusChanged(false);
+ }
+
// Animate the task bar out of the first task view
animate()
- .translationY(-getMeasuredHeight())
+ .alpha(0f)
.setStartDelay(0)
- .setInterpolator(mConfig.fastOutLinearInInterpolator)
+ .setInterpolator(mConfig.linearOutSlowInInterpolator)
.setDuration(mConfig.taskBarExitAnimDuration)
.withStartAction(preAnimRunnable)
.withEndAction(new Runnable() {
@@ -236,6 +253,7 @@
post(postAnimRunnable);
}
})
+ .withLayer()
.start();
}
@@ -278,10 +296,10 @@
/** Notifies the associated TaskView has been focused. */
void onTaskViewFocusChanged(boolean focused) {
boolean isRunning = false;
- if (mBackgroundColorAnimator != null) {
- isRunning = mBackgroundColorAnimator.isRunning();
- mBackgroundColorAnimator.removeAllUpdateListeners();
- mBackgroundColorAnimator.cancel();
+ if (mFocusAnimator != null) {
+ isRunning = mFocusAnimator.isRunning();
+ mFocusAnimator.removeAllListeners();
+ mFocusAnimator.cancel();
}
if (focused) {
int secondaryColor = getSecondaryColor(mCurrentPrimaryColor, mCurrentPrimaryColorIsDark);
@@ -302,42 +320,54 @@
// Pulse the background color
int currentColor = mBackgroundColor.getColor();
int lightPrimaryColor = getSecondaryColor(mCurrentPrimaryColor, mCurrentPrimaryColorIsDark);
- mBackgroundColorAnimator = ValueAnimator.ofObject(new ArgbEvaluator(), lightPrimaryColor,
- currentColor);
- mBackgroundColorAnimator.addListener(new AnimatorListenerAdapter() {
+ ValueAnimator backgroundColor = ValueAnimator.ofObject(new ArgbEvaluator(),
+ lightPrimaryColor, currentColor);
+ backgroundColor.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationStart(Animator animation) {
- mBackground.setState(new int[] {});
+ mBackground.setState(new int[]{});
}
});
- mBackgroundColorAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
+ backgroundColor.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
mBackgroundColor.setColor((Integer) animation.getAnimatedValue());
}
});
- mBackgroundColorAnimator.setRepeatCount(ValueAnimator.INFINITE);
- mBackgroundColorAnimator.setRepeatMode(ValueAnimator.REVERSE);
- mBackgroundColorAnimator.setStartDelay(750);
- mBackgroundColorAnimator.setDuration(750);
- mBackgroundColorAnimator.start();
+ backgroundColor.setRepeatCount(ValueAnimator.INFINITE);
+ backgroundColor.setRepeatMode(ValueAnimator.REVERSE);
+ // Pulse the translation
+ ObjectAnimator translation = ObjectAnimator.ofFloat(this, "translationZ", 15f);
+ translation.setRepeatCount(ValueAnimator.INFINITE);
+ translation.setRepeatMode(ValueAnimator.REVERSE);
+
+ mFocusAnimator = new AnimatorSet();
+ mFocusAnimator.playTogether(backgroundColor, translation);
+ mFocusAnimator.setStartDelay(750);
+ mFocusAnimator.setDuration(750);
+ mFocusAnimator.start();
} else {
if (isRunning) {
// Restore the background color
int currentColor = mBackgroundColor.getColor();
- mBackgroundColorAnimator = ValueAnimator.ofObject(new ArgbEvaluator(), currentColor,
- mCurrentPrimaryColor);
- mBackgroundColorAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
+ ValueAnimator backgroundColor = ValueAnimator.ofObject(new ArgbEvaluator(),
+ currentColor, mCurrentPrimaryColor);
+ backgroundColor.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
mBackgroundColor.setColor((Integer) animation.getAnimatedValue());
}
});
- mBackgroundColorAnimator.setRepeatCount(0);
- mBackgroundColorAnimator.setDuration(150);
- mBackgroundColorAnimator.start();
+ // Restore the translation
+ ObjectAnimator translation = ObjectAnimator.ofFloat(this, "translationZ", 0f);
+
+ mFocusAnimator = new AnimatorSet();
+ mFocusAnimator.playTogether(backgroundColor, translation);
+ mFocusAnimator.setDuration(150);
+ mFocusAnimator.start();
} else {
mBackground.setState(new int[] {});
+ setTranslationZ(0f);
}
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
index 42ae0c9..d398bc1 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
@@ -36,7 +36,6 @@
import android.widget.FrameLayout;
import android.widget.LinearLayout;
import android.widget.TextView;
-
import com.android.systemui.R;
import com.android.systemui.qs.QSPanel;
import com.android.systemui.statusbar.ExpandableView;
@@ -160,6 +159,7 @@
private boolean mShadeEmpty;
private boolean mQsScrimEnabled = true;
+ private boolean mLastAnnouncementWasQuickSettings;
public NotificationPanelView(Context context, AttributeSet attrs) {
super(context, attrs);
@@ -425,8 +425,8 @@
@Override
public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) {
if (event.getEventType() == AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED) {
- event.getText()
- .add(getContext().getString(R.string.accessibility_desc_notification_shade));
+ event.getText().add(getKeyguardOrLockScreenString());
+ mLastAnnouncementWasQuickSettings = false;
return true;
}
@@ -987,6 +987,10 @@
setQsExpanded(true);
} else if (height <= mQsMinExpansionHeight && mQsExpanded) {
setQsExpanded(false);
+ if (mLastAnnouncementWasQuickSettings && !mTracking) {
+ announceForAccessibility(getKeyguardOrLockScreenString());
+ mLastAnnouncementWasQuickSettings = false;
+ }
}
mQsExpansionHeight = height;
mHeader.setExpansion(getHeaderExpansionFraction());
@@ -1000,6 +1004,22 @@
&& !mStackScrollerOverscrolling && mQsScrimEnabled) {
mQsNavbarScrim.setAlpha(getQsExpansionFraction());
}
+
+ // Upon initialisation when we are not layouted yet we don't want to announce that we are
+ // fully expanded, hence the != 0.0f check.
+ if (height != 0.0f && mQsFullyExpanded && !mLastAnnouncementWasQuickSettings) {
+ announceForAccessibility(getContext().getString(
+ R.string.accessibility_desc_quick_settings));
+ mLastAnnouncementWasQuickSettings = true;
+ }
+ }
+
+ private String getKeyguardOrLockScreenString() {
+ if (mStatusBarState == StatusBarState.KEYGUARD) {
+ return getContext().getString(R.string.accessibility_desc_lock_screen);
+ } else {
+ return getContext().getString(R.string.accessibility_desc_notification_shade);
+ }
}
private void updateNotificationScrim(float height) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java
index 4e9f37d..15a7047 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java
@@ -602,6 +602,8 @@
mPhoneSignalIconId = R.drawable.stat_sys_signal_null;
mQSPhoneSignalIconId = R.drawable.ic_qs_signal_no_signal;
mDataSignalIconId = R.drawable.stat_sys_signal_null;
+ mContentDescriptionPhoneSignal = mContext.getString(
+ AccessibilityContentDescriptions.PHONE_SIGNAL_STRENGTH[0]);
} else {
if (mSignalStrength == null) {
if (CHATTY) Log.d(TAG, "updateTelephonySignalStrength: mSignalStrength == null");
@@ -665,8 +667,7 @@
mDataIconList = TelephonyIcons.DATA_G[mInetCondition];
mDataTypeIconId = 0;
mQSDataTypeIconId = 0;
- mContentDescriptionDataType = mContext.getString(
- R.string.accessibility_data_connection_gprs);
+ mContentDescriptionDataType = "";
break;
} else {
// fall through
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java
index 47e3e73..d53aa47 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java
@@ -508,9 +508,9 @@
setTitle(R.string.guest_exit_guest_dialog_title);
setMessage(context.getString(R.string.guest_exit_guest_dialog_message));
setButton(DialogInterface.BUTTON_NEGATIVE,
- context.getString(android.R.string.no), this);
+ context.getString(android.R.string.cancel), this);
setButton(DialogInterface.BUTTON_POSITIVE,
- context.getString(android.R.string.yes), this);
+ context.getString(R.string.guest_exit_guest_dialog_remove), this);
setCanceledOnTouchOutside(false);
mGuestId = guestId;
}
diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumePanel.java b/packages/SystemUI/src/com/android/systemui/volume/VolumePanel.java
index b05c242..51876b8 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/VolumePanel.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/VolumePanel.java
@@ -37,7 +37,7 @@
import android.media.ToneGenerator;
import android.media.VolumeProvider;
import android.media.session.MediaController;
-import android.media.session.MediaController.VolumeInfo;
+import android.media.session.MediaController.AudioInfo;
import android.net.Uri;
import android.os.Handler;
import android.os.Message;
@@ -537,8 +537,8 @@
if (mStreamControls != null) {
StreamControl sc = mStreamControls.get(streamType);
if (sc != null && sc.controller != null) {
- VolumeInfo vi = sc.controller.getVolumeInfo();
- return vi.getMaxVolume();
+ AudioInfo ai = sc.controller.getAudioInfo();
+ return ai.getMaxVolume();
}
}
return -1;
@@ -554,8 +554,8 @@
if (mStreamControls != null) {
StreamControl sc = mStreamControls.get(streamType);
if (sc != null && sc.controller != null) {
- VolumeInfo vi = sc.controller.getVolumeInfo();
- return vi.getCurrentVolume();
+ AudioInfo ai = sc.controller.getAudioInfo();
+ return ai.getCurrentVolume();
}
}
return -1;
@@ -990,7 +990,7 @@
// We still don't have one, ignore the command.
Log.w(mTag, "sent remote volume change without a controller!");
} else {
- VolumeInfo vi = controller.getVolumeInfo();
+ AudioInfo vi = controller.getAudioInfo();
index = vi.getCurrentVolume();
max = vi.getMaxVolume();
if ((vi.getVolumeControl() & VolumeProvider.VOLUME_CONTROL_FIXED) != 0) {
@@ -1362,7 +1362,7 @@
};
private final MediaController.Callback mMediaControllerCb = new MediaController.Callback() {
- public void onVolumeInfoChanged(VolumeInfo info) {
+ public void onAudioInfoChanged(AudioInfo info) {
onRemoteVolumeUpdateIfShown();
}
};
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindow.java b/policy/src/com/android/internal/policy/impl/PhoneWindow.java
index 964acbd..73358c8 100644
--- a/policy/src/com/android/internal/policy/impl/PhoneWindow.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindow.java
@@ -3559,6 +3559,10 @@
if (transitionId != -1 && transitionId != R.transition.no_transition) {
TransitionInflater inflater = TransitionInflater.from(getContext());
transition = inflater.inflateTransition(transitionId);
+ if (transition instanceof TransitionSet &&
+ ((TransitionSet)transition).getTransitionCount() == 0) {
+ transition = null;
+ }
}
return transition;
}
diff --git a/rs/java/android/renderscript/Allocation.java b/rs/java/android/renderscript/Allocation.java
index 7db85f2..3cda6de 100644
--- a/rs/java/android/renderscript/Allocation.java
+++ b/rs/java/android/renderscript/Allocation.java
@@ -1868,7 +1868,7 @@
}
}
- static void sendBufferNotification(int id) {
+ static void sendBufferNotification(long id) {
synchronized(mAllocationMap) {
Allocation a = mAllocationMap.get(new Long(id));
diff --git a/rs/java/android/renderscript/RenderScript.java b/rs/java/android/renderscript/RenderScript.java
index 340efef..6c5c508 100644
--- a/rs/java/android/renderscript/RenderScript.java
+++ b/rs/java/android/renderscript/RenderScript.java
@@ -1156,7 +1156,12 @@
}
if (msg == RS_MESSAGE_TO_CLIENT_NEW_BUFFER) {
- Allocation.sendBufferNotification(subID);
+ if (mRS.nContextGetUserMessage(mRS.mContext, rbuf) !=
+ RS_MESSAGE_TO_CLIENT_NEW_BUFFER) {
+ throw new RSDriverException("Error processing message from RenderScript.");
+ }
+ long bufferID = ((long)rbuf[1] << 32L) + ((long)rbuf[0] & 0xffffffffL);
+ Allocation.sendBufferNotification(bufferID);
continue;
}
diff --git a/rs/jni/android_renderscript_RenderScript.cpp b/rs/jni/android_renderscript_RenderScript.cpp
index 16df377..13a649a 100644
--- a/rs/jni/android_renderscript_RenderScript.cpp
+++ b/rs/jni/android_renderscript_RenderScript.cpp
@@ -222,7 +222,7 @@
nDeviceCreate(JNIEnv *_env, jobject _this)
{
LOG_API("nDeviceCreate");
- return (jlong)rsDeviceCreate();
+ return (jlong)(uintptr_t)rsDeviceCreate();
}
static void
@@ -243,7 +243,7 @@
nContextCreate(JNIEnv *_env, jobject _this, jlong dev, jint ver, jint sdkVer, jint ct)
{
LOG_API("nContextCreate");
- return (jlong)rsContextCreate((RsDevice)dev, ver, sdkVer, (RsContextType)ct, 0);
+ return (jlong)(uintptr_t)rsContextCreate((RsDevice)dev, ver, sdkVer, (RsContextType)ct, 0);
}
static jlong
@@ -267,7 +267,7 @@
sc.samplesQ = samplesQ;
LOG_API("nContextCreateGL");
- return (jlong)rsContextCreateGL((RsDevice)dev, ver, sdkVer, sc, dpi);
+ return (jlong)(uintptr_t)rsContextCreateGL((RsDevice)dev, ver, sdkVer, sc, dpi);
}
static void
@@ -409,7 +409,7 @@
nElementCreate(JNIEnv *_env, jobject _this, jlong con, jlong type, jint kind, jboolean norm, jint size)
{
LOG_API("nElementCreate, con(%p), type(%i), kind(%i), norm(%i), size(%i)", (RsContext)con, type, kind, norm, size);
- return (jlong)rsElementCreate((RsContext)con, (RsDataType)type, (RsDataKind)kind, norm, size);
+ return (jlong)(uintptr_t)rsElementCreate((RsContext)con, (RsDataType)type, (RsDataKind)kind, norm, size);
}
static jlong
@@ -435,7 +435,7 @@
const char **nameArray = names.c_str();
size_t *sizeArray = names.c_str_len();
- jlong id = (jlong)rsElementCreate2((RsContext)con,
+ jlong id = (jlong)(uintptr_t)rsElementCreate2((RsContext)con,
(const RsElement *)ids, fieldCount,
nameArray, fieldCount * sizeof(size_t), sizeArray,
(const uint32_t *)arraySizes, fieldCount);
@@ -445,7 +445,7 @@
_env->ReleaseLongArrayElements(_ids, jIds, JNI_ABORT);
_env->ReleaseIntArrayElements(_arraySizes, jArraySizes, JNI_ABORT);
- return (jlong)id;
+ return (jlong)(uintptr_t)id;
}
static void
@@ -483,7 +483,7 @@
rsaElementGetSubElements((RsContext)con, (RsElement)id, ids, names, arraySizes, (uint32_t)dataSize);
for(uint32_t i = 0; i < dataSize; i++) {
- const jlong id = (jlong)ids[i];
+ const jlong id = (jlong)(uintptr_t)ids[i];
const jint arraySize = (jint)arraySizes[i];
_env->SetObjectArrayElement(_names, i, _env->NewStringUTF(names[i]));
_env->SetLongArrayRegion(_IDs, i, 1, &id);
@@ -504,7 +504,7 @@
LOG_API("nTypeCreate, con(%p) eid(%p), x(%i), y(%i), z(%i), mips(%i), faces(%i), yuv(%i)",
(RsContext)con, eid, dimx, dimy, dimz, mips, faces, yuv);
- return (jlong)rsTypeCreate((RsContext)con, (RsElement)eid, dimx, dimy, dimz, mips, faces, yuv);
+ return (jlong)(uintptr_t)rsTypeCreate((RsContext)con, (RsElement)eid, dimx, dimy, dimz, mips, faces, yuv);
}
static void
@@ -521,7 +521,7 @@
rsaTypeGetNativeData((RsContext)con, (RsType)id, typeData, 6);
for(jint i = 0; i < elementCount; i ++) {
- const jlong data = (jlong)typeData[i];
+ const jlong data = (jlong)(uintptr_t)typeData[i];
_env->SetLongArrayRegion(_typeData, i, 1, &data);
}
}
@@ -532,7 +532,7 @@
nAllocationCreateTyped(JNIEnv *_env, jobject _this, jlong con, jlong type, jint mips, jint usage, jlong pointer)
{
LOG_API("nAllocationCreateTyped, con(%p), type(%p), mip(%i), usage(%i), ptr(%p)", (RsContext)con, (RsElement)type, mips, usage, (void *)pointer);
- return (jlong) rsAllocationCreateTyped((RsContext)con, (RsType)type, (RsAllocationMipmapControl)mips, (uint32_t)usage, (uintptr_t)pointer);
+ return (jlong)(uintptr_t) rsAllocationCreateTyped((RsContext)con, (RsType)type, (RsAllocationMipmapControl)mips, (uint32_t)usage, (uintptr_t)pointer);
}
static void
@@ -600,7 +600,7 @@
bitmap.lockPixels();
const void* ptr = bitmap.getPixels();
- jlong id = (jlong)rsAllocationCreateFromBitmap((RsContext)con,
+ jlong id = (jlong)(uintptr_t)rsAllocationCreateFromBitmap((RsContext)con,
(RsType)type, (RsAllocationMipmapControl)mip,
ptr, bitmap.getSize(), usage);
bitmap.unlockPixels();
@@ -616,7 +616,7 @@
bitmap.lockPixels();
const void* ptr = bitmap.getPixels();
- jlong id = (jlong)rsAllocationCreateTyped((RsContext)con,
+ jlong id = (jlong)(uintptr_t)rsAllocationCreateTyped((RsContext)con,
(RsType)type, (RsAllocationMipmapControl)mip,
(uint32_t)usage, (uintptr_t)ptr);
bitmap.unlockPixels();
@@ -632,7 +632,7 @@
bitmap.lockPixels();
const void* ptr = bitmap.getPixels();
- jlong id = (jlong)rsAllocationCubeCreateFromBitmap((RsContext)con,
+ jlong id = (jlong)(uintptr_t)rsAllocationCubeCreateFromBitmap((RsContext)con,
(RsType)type, (RsAllocationMipmapControl)mip,
ptr, bitmap.getSize(), usage);
bitmap.unlockPixels();
@@ -810,7 +810,7 @@
nAllocationGetType(JNIEnv *_env, jobject _this, jlong con, jlong a)
{
LOG_API("nAllocationGetType, con(%p), a(%p)", (RsContext)con, (RsAllocation)a);
- return (jlong) rsaAllocationGetType((RsContext)con, (RsAllocation)a);
+ return (jlong)(uintptr_t) rsaAllocationGetType((RsContext)con, (RsAllocation)a);
}
static void
@@ -828,7 +828,7 @@
Asset* asset = reinterpret_cast<Asset*>(native_asset);
ALOGV("______nFileA3D %p", asset);
- jlong id = (jlong)rsaFileA3DCreateFromMemory((RsContext)con, asset->getBuffer(false), asset->getLength());
+ jlong id = (jlong)(uintptr_t)rsaFileA3DCreateFromMemory((RsContext)con, asset->getBuffer(false), asset->getLength());
return id;
}
@@ -846,7 +846,7 @@
return 0;
}
- jlong id = (jlong)rsaFileA3DCreateFromAsset((RsContext)con, asset);
+ jlong id = (jlong)(uintptr_t)rsaFileA3DCreateFromAsset((RsContext)con, asset);
return id;
}
@@ -854,7 +854,7 @@
nFileA3DCreateFromFile(JNIEnv *_env, jobject _this, jlong con, jstring fileName)
{
AutoJavaStringToUTF8 fileNameUTF(_env, fileName);
- jlong id = (jlong)rsaFileA3DCreateFromFile((RsContext)con, fileNameUTF.c_str());
+ jlong id = (jlong)(uintptr_t)rsaFileA3DCreateFromFile((RsContext)con, fileNameUTF.c_str());
return id;
}
@@ -887,7 +887,7 @@
nFileA3DGetEntryByIndex(JNIEnv *_env, jobject _this, jlong con, jlong fileA3D, jint index)
{
ALOGV("______nFileA3D %p", (RsFile) fileA3D);
- jlong id = (jlong)rsaFileA3DGetEntryByIndex((RsContext)con, (uint32_t)index, (RsFile)fileA3D);
+ jlong id = (jlong)(uintptr_t)rsaFileA3DGetEntryByIndex((RsContext)con, (uint32_t)index, (RsFile)fileA3D);
return id;
}
@@ -898,7 +898,7 @@
jstring fileName, jfloat fontSize, jint dpi)
{
AutoJavaStringToUTF8 fileNameUTF(_env, fileName);
- jlong id = (jlong)rsFontCreateFromFile((RsContext)con,
+ jlong id = (jlong)(uintptr_t)rsFontCreateFromFile((RsContext)con,
fileNameUTF.c_str(), fileNameUTF.length(),
fontSize, dpi);
@@ -912,7 +912,7 @@
Asset* asset = reinterpret_cast<Asset*>(native_asset);
AutoJavaStringToUTF8 nameUTF(_env, name);
- jlong id = (jlong)rsFontCreateFromMemory((RsContext)con,
+ jlong id = (jlong)(uintptr_t)rsFontCreateFromMemory((RsContext)con,
nameUTF.c_str(), nameUTF.length(),
fontSize, dpi,
asset->getBuffer(false), asset->getLength());
@@ -934,7 +934,7 @@
return 0;
}
- jlong id = (jlong)rsFontCreateFromMemory((RsContext)con,
+ jlong id = (jlong)(uintptr_t)rsFontCreateFromMemory((RsContext)con,
str.c_str(), str.length(),
fontSize, dpi,
asset->getBuffer(false), asset->getLength());
@@ -1283,7 +1283,7 @@
//rsScriptCSetText((RsContext)con, (const char *)script_ptr, length);
- ret = (jlong)rsScriptCCreate((RsContext)con,
+ ret = (jlong)(uintptr_t)rsScriptCCreate((RsContext)con,
resNameUTF.c_str(), resNameUTF.length(),
cacheDirUTF.c_str(), cacheDirUTF.length(),
(const char *)script_ptr, length);
@@ -1294,28 +1294,28 @@
_exception ? JNI_ABORT: 0);
}
- return (jlong)ret;
+ return (jlong)(uintptr_t)ret;
}
static jlong
nScriptIntrinsicCreate(JNIEnv *_env, jobject _this, jlong con, jint id, jlong eid)
{
LOG_API("nScriptIntrinsicCreate, con(%p) id(%i) element(%p)", (RsContext)con, id, (void *)eid);
- return (jlong)rsScriptIntrinsicCreate((RsContext)con, id, (RsElement)eid);
+ return (jlong)(uintptr_t)rsScriptIntrinsicCreate((RsContext)con, id, (RsElement)eid);
}
static jlong
nScriptKernelIDCreate(JNIEnv *_env, jobject _this, jlong con, jlong sid, jint slot, jint sig)
{
LOG_API("nScriptKernelIDCreate, con(%p) script(%p), slot(%i), sig(%i)", (RsContext)con, (void *)sid, slot, sig);
- return (jlong)rsScriptKernelIDCreate((RsContext)con, (RsScript)sid, slot, sig);
+ return (jlong)(uintptr_t)rsScriptKernelIDCreate((RsContext)con, (RsScript)sid, slot, sig);
}
static jlong
nScriptFieldIDCreate(JNIEnv *_env, jobject _this, jlong con, jlong sid, jint slot)
{
LOG_API("nScriptFieldIDCreate, con(%p) script(%p), slot(%i)", (RsContext)con, (void *)sid, slot);
- return (jlong)rsScriptFieldIDCreate((RsContext)con, (RsScript)sid, slot);
+ return (jlong)(uintptr_t)rsScriptFieldIDCreate((RsContext)con, (RsScript)sid, slot);
}
static jlong
@@ -1359,7 +1359,7 @@
typesPtr[i] = (RsType)jTypesPtr[i];
}
- jlong id = (jlong)rsScriptGroupCreate((RsContext)con,
+ jlong id = (jlong)(uintptr_t)rsScriptGroupCreate((RsContext)con,
(RsScriptKernelID *)kernelsPtr, kernelsLen * sizeof(RsScriptKernelID),
(RsScriptKernelID *)srcPtr, srcLen * sizeof(RsScriptKernelID),
(RsScriptKernelID *)dstkPtr, dstkLen * sizeof(RsScriptKernelID),
@@ -1412,7 +1412,7 @@
jint depthFunc)
{
LOG_API("nProgramStoreCreate, con(%p)", (RsContext)con);
- return (jlong)rsProgramStoreCreate((RsContext)con, colorMaskR, colorMaskG, colorMaskB, colorMaskA,
+ return (jlong)(uintptr_t)rsProgramStoreCreate((RsContext)con, colorMaskR, colorMaskG, colorMaskB, colorMaskA,
depthMask, ditherEnable, (RsBlendSrcFunc)srcFunc,
(RsBlendDstFunc)destFunc, (RsDepthFunc)depthFunc);
}
@@ -1461,7 +1461,7 @@
for(int i = 0; i < paramLen; ++i) {
paramPtr[i] = (uintptr_t)jParamPtr[i];
}
- jlong ret = (jlong)rsProgramFragmentCreate((RsContext)con, shaderUTF.c_str(), shaderUTF.length(),
+ jlong ret = (jlong)(uintptr_t)rsProgramFragmentCreate((RsContext)con, shaderUTF.c_str(), shaderUTF.length(),
nameArray, texCount, sizeArray,
paramPtr, paramLen);
@@ -1493,7 +1493,7 @@
paramPtr[i] = (uintptr_t)jParamPtr[i];
}
- jlong ret = (jlong)rsProgramVertexCreate((RsContext)con, shaderUTF.c_str(), shaderUTF.length(),
+ jlong ret = (jlong)(uintptr_t)rsProgramVertexCreate((RsContext)con, shaderUTF.c_str(), shaderUTF.length(),
nameArray, texCount, sizeArray,
paramPtr, paramLen);
@@ -1508,7 +1508,7 @@
nProgramRasterCreate(JNIEnv *_env, jobject _this, jlong con, jboolean pointSprite, jint cull)
{
LOG_API("nProgramRasterCreate, con(%p), pointSprite(%i), cull(%i)", (RsContext)con, pointSprite, cull);
- return (jlong)rsProgramRasterCreate((RsContext)con, pointSprite, (RsCullMode)cull);
+ return (jlong)(uintptr_t)rsProgramRasterCreate((RsContext)con, pointSprite, (RsCullMode)cull);
}
@@ -1557,7 +1557,7 @@
jint wrapS, jint wrapT, jint wrapR, jfloat aniso)
{
LOG_API("nSamplerCreate, con(%p)", (RsContext)con);
- return (jlong)rsSamplerCreate((RsContext)con,
+ return (jlong)(uintptr_t)rsSamplerCreate((RsContext)con,
(RsSamplerValue)magFilter,
(RsSamplerValue)minFilter,
(RsSamplerValue)wrapS,
@@ -1572,7 +1572,7 @@
nPathCreate(JNIEnv *_env, jobject _this, jlong con, jint prim, jboolean isStatic, jlong _vtx, jlong _loop, jfloat q) {
LOG_API("nPathCreate, con(%p)", (RsContext)con);
- jlong id = (jlong)rsPathCreate((RsContext)con, (RsPathPrimitive)prim, isStatic,
+ jlong id = (jlong)(uintptr_t)rsPathCreate((RsContext)con, (RsPathPrimitive)prim, isStatic,
(RsAllocation)_vtx,
(RsAllocation)_loop, q);
return id;
@@ -1600,7 +1600,7 @@
jint primLen = _env->GetArrayLength(_prim);
jint *primPtr = _env->GetIntArrayElements(_prim, NULL);
- jlong id = (jlong)rsMeshCreate((RsContext)con,
+ jlong id = (jlong)(uintptr_t)rsMeshCreate((RsContext)con,
(RsAllocation *)vtxPtr, vtxLen,
(RsAllocation *)idxPtr, idxLen,
(uint32_t *)primPtr, primLen);
@@ -1640,7 +1640,7 @@
rsaMeshGetVertices((RsContext)con, (RsMesh)mesh, allocs, (uint32_t)numVtxIDs);
for(jint i = 0; i < numVtxIDs; i ++) {
- const jlong alloc = (jlong)allocs[i];
+ const jlong alloc = (jlong)(uintptr_t)allocs[i];
_env->SetLongArrayRegion(_ids, i, 1, &alloc);
}
@@ -1658,7 +1658,7 @@
rsaMeshGetIndices((RsContext)con, (RsMesh)mesh, allocs, prims, (uint32_t)numIndices);
for(jint i = 0; i < numIndices; i ++) {
- const jlong alloc = (jlong)allocs[i];
+ const jlong alloc = (jlong)(uintptr_t)allocs[i];
const jint prim = (jint)prims[i];
_env->SetLongArrayRegion(_idxIds, i, 1, &alloc);
_env->SetIntArrayRegion(_primitives, i, 1, &prim);
diff --git a/services/core/java/com/android/server/am/CoreSettingsObserver.java b/services/core/java/com/android/server/am/CoreSettingsObserver.java
index 4c887dd..0dc163b 100644
--- a/services/core/java/com/android/server/am/CoreSettingsObserver.java
+++ b/services/core/java/com/android/server/am/CoreSettingsObserver.java
@@ -41,12 +41,17 @@
String, Class<?>>();
private static final Map<String, Class<?>> sSystemSettingToTypeMap = new HashMap<
String, Class<?>>();
+ private static final Map<String, Class<?>> sGlobalSettingToTypeMap = new HashMap<
+ String, Class<?>>();
static {
sSecureSettingToTypeMap.put(Settings.Secure.LONG_PRESS_TIMEOUT, int.class);
// add other secure settings here...
sSystemSettingToTypeMap.put(Settings.System.TIME_12_24, String.class);
// add other system settings here...
+
+ sGlobalSettingToTypeMap.put(Settings.Global.DEBUG_VIEW_ATTRIBUTES, int.class);
+ // add other global settings here...
}
private final Bundle mCoreSettings = new Bundle();
@@ -74,6 +79,7 @@
private void sendCoreSettings() {
populateSettings(mCoreSettings, sSecureSettingToTypeMap);
populateSettings(mCoreSettings, sSystemSettingToTypeMap);
+ populateSettings(mCoreSettings, sGlobalSettingToTypeMap);
mActivityManagerService.onCoreSettingsChange(mCoreSettings);
}
@@ -89,6 +95,12 @@
mActivityManagerService.mContext.getContentResolver().registerContentObserver(
uri, false, this);
}
+
+ for (String setting : sGlobalSettingToTypeMap.keySet()) {
+ Uri uri = Settings.Global.getUriFor(setting);
+ mActivityManagerService.mContext.getContentResolver().registerContentObserver(
+ uri, false, this);
+ }
}
private void populateSettings(Bundle snapshot, Map<String, Class<?>> map) {
@@ -101,32 +113,40 @@
final String value;
if (map == sSecureSettingToTypeMap) {
value = Settings.Secure.getString(context.getContentResolver(), setting);
- } else {
+ } else if (map == sSystemSettingToTypeMap) {
value = Settings.System.getString(context.getContentResolver(), setting);
+ } else {
+ value = Settings.Global.getString(context.getContentResolver(), setting);
}
snapshot.putString(setting, value);
} else if (type == int.class) {
final int value;
if (map == sSecureSettingToTypeMap) {
value = Settings.Secure.getInt(context.getContentResolver(), setting);
- } else {
+ } else if (map == sSystemSettingToTypeMap) {
value = Settings.System.getInt(context.getContentResolver(), setting);
+ } else {
+ value = Settings.Global.getInt(context.getContentResolver(), setting);
}
snapshot.putInt(setting, value);
} else if (type == float.class) {
final float value;
if (map == sSecureSettingToTypeMap) {
value = Settings.Secure.getFloat(context.getContentResolver(), setting);
- } else {
+ } else if (map == sSystemSettingToTypeMap) {
value = Settings.System.getFloat(context.getContentResolver(), setting);
+ } else {
+ value = Settings.Global.getFloat(context.getContentResolver(), setting);
}
snapshot.putFloat(setting, value);
} else if (type == long.class) {
final long value;
if (map == sSecureSettingToTypeMap) {
value = Settings.Secure.getLong(context.getContentResolver(), setting);
- } else {
+ } else if (map == sSystemSettingToTypeMap) {
value = Settings.System.getLong(context.getContentResolver(), setting);
+ } else {
+ value = Settings.Global.getLong(context.getContentResolver(), setting);
}
snapshot.putLong(setting, value);
}
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecKeycode.java b/services/core/java/com/android/server/hdmi/HdmiCecKeycode.java
index 46b2b3e..aed5dcc 100644
--- a/services/core/java/com/android/server/hdmi/HdmiCecKeycode.java
+++ b/services/core/java/com/android/server/hdmi/HdmiCecKeycode.java
@@ -155,7 +155,7 @@
}
/**
- * A mapping between andorid and cec keycode.
+ * A mapping between Android and CEC keycode.
*
* <p>Normal implementation of this looks like
* <pre>
@@ -174,43 +174,28 @@
private static class KeycodeEntry {
private final int mAndroidKeycode;
private final int mCecKeycode;
- private final int mParam;
private final boolean mIsRepeatable;
- private KeycodeEntry(int androidKeycode, int cecKeycode, int param, boolean isRepeatable) {
+ private KeycodeEntry(int androidKeycode, int cecKeycode, boolean isRepeatable) {
mAndroidKeycode = androidKeycode;
mCecKeycode = cecKeycode;
- mParam = param;
mIsRepeatable = isRepeatable;
}
private KeycodeEntry(int androidKeycode, int cecKeycode) {
- this(androidKeycode, cecKeycode, NO_PARAM, true);
+ this(androidKeycode, cecKeycode, true);
}
- private KeycodeEntry(int androidKeycode, int cecKeycode, boolean isRepeatable) {
- this(androidKeycode, cecKeycode, NO_PARAM, isRepeatable);
- }
-
- private byte[] toCecKeycodeIfMatched(int androidKeycode) {
+ private int toCecKeycodeIfMatched(int androidKeycode) {
if (mAndroidKeycode == androidKeycode) {
- if (mParam == NO_PARAM) {
- return new byte[] {
- (byte) (mCecKeycode & 0xFF)
- };
- } else {
- return new byte[] {
- (byte) (mCecKeycode & 0xFF),
- (byte) (mParam & 0xFF)
- };
- }
+ return mCecKeycode;
} else {
- return null;
+ return UNSUPPORTED_KEYCODE;
}
}
- private int toAndroidKeycodeIfMatched(int cecKeycode, int param) {
- if (cecKeycode == mCecKeycode && mParam == param) {
+ private int toAndroidKeycodeIfMatched(int cecKeycode) {
+ if (cecKeycode == mCecKeycode) {
return mAndroidKeycode;
} else {
return UNSUPPORTED_KEYCODE;
@@ -365,29 +350,28 @@
* Translate Android keycode to Hdmi Cec keycode.
*
* @param keycode Android keycode. For details, refer {@link KeyEvent}
- * @return array of byte which contains cec keycode and param if it has;
- * return null if failed to find matched cec keycode
+ * @return single byte CEC keycode if matched.
*/
- static byte[] androidKeyToCecKey(int keycode) {
+ static int androidKeyToCecKey(int keycode) {
for (int i = 0; i < KEYCODE_ENTRIES.length; ++i) {
- byte[] cecKeycode = KEYCODE_ENTRIES[i].toCecKeycodeIfMatched(keycode);
- if (cecKeycode != null) {
+ int cecKeycode = KEYCODE_ENTRIES[i].toCecKeycodeIfMatched(keycode);
+ if (cecKeycode != UNSUPPORTED_KEYCODE) {
return cecKeycode;
}
}
- return null;
+ return UNSUPPORTED_KEYCODE;
}
/**
* Translate Hdmi CEC keycode to Android keycode.
*
- * @param keycode Cec keycode. If has no param, put {@link #NO_PARAM}
+ * @param keycode CEC keycode
* @return cec keycode corresponding to the given android keycode.
* If finds no matched keycode, return {@link #UNSUPPORTED_KEYCODE}
*/
- static int cecKeyToAndroidKey(int keycode, int param) {
+ static int cecKeyToAndroidKey(int keycode) {
for (int i = 0; i < KEYCODE_ENTRIES.length; ++i) {
- int androidKey = KEYCODE_ENTRIES[i].toAndroidKeycodeIfMatched(keycode, param);
+ int androidKey = KEYCODE_ENTRIES[i].toAndroidKeycodeIfMatched(keycode);
if (androidKey != UNSUPPORTED_KEYCODE) {
return androidKey;
}
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecLocalDevice.java b/services/core/java/com/android/server/hdmi/HdmiCecLocalDevice.java
index 4862f93..b43ad1b 100644
--- a/services/core/java/com/android/server/hdmi/HdmiCecLocalDevice.java
+++ b/services/core/java/com/android/server/hdmi/HdmiCecLocalDevice.java
@@ -405,8 +405,9 @@
final long downTime = SystemClock.uptimeMillis();
final byte[] params = message.getParams();
- final int keycode = HdmiCecKeycode.cecKeyToAndroidKey(params[0],
- params.length > 1 ? params[1] : HdmiCecKeycode.NO_PARAM);
+ // Note that we don't support parameterized keycode now.
+ // TODO: translate parameterized keycode as well.
+ final int keycode = HdmiCecKeycode.cecKeyToAndroidKey(params[0]);
int keyRepeatCount = 0;
if (mLastKeycode != HdmiCecKeycode.UNSUPPORTED_KEYCODE) {
if (keycode == mLastKeycode) {
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java
index 809fef4..126a56d 100644
--- a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java
+++ b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java
@@ -1007,10 +1007,8 @@
/**
* Return external input devices.
*/
- List<HdmiDeviceInfo> getSafeExternalInputs() {
- synchronized (mLock) {
- return mSafeExternalInputs;
- }
+ List<HdmiDeviceInfo> getSafeExternalInputsLocked() {
+ return mSafeExternalInputs;
}
@ServiceThreadOnly
diff --git a/services/core/java/com/android/server/hdmi/HdmiControlService.java b/services/core/java/com/android/server/hdmi/HdmiControlService.java
index 14c066e..32d97ba 100644
--- a/services/core/java/com/android/server/hdmi/HdmiControlService.java
+++ b/services/core/java/com/android/server/hdmi/HdmiControlService.java
@@ -16,6 +16,8 @@
package com.android.server.hdmi;
+import static android.hardware.hdmi.HdmiControlManager.DEVICE_EVENT_ADD_DEVICE;
+import static android.hardware.hdmi.HdmiControlManager.DEVICE_EVENT_REMOVE_DEVICE;
import static com.android.server.hdmi.Constants.DISABLED;
import static com.android.server.hdmi.Constants.ENABLED;
import static com.android.server.hdmi.Constants.OPTION_CEC_AUTO_WAKEUP;
@@ -202,6 +204,9 @@
@GuardedBy("mLock")
private boolean mMhlInputChangeEnabled;
+ @GuardedBy("mLock")
+ private List<HdmiDeviceInfo> mMhlDevices;
+
// List of listeners registered by callers that want to get notified of
// system audio mode changes.
private final ArrayList<IHdmiSystemAudioModeChangeListener>
@@ -293,6 +298,7 @@
Slog.i(TAG, "Device does not support MHL-control.");
}
initPortInfo();
+ mMhlDevices = Collections.emptyList();
mMessageValidator = new HdmiCecMessageValidator(this);
publishBinderService(Context.HDMI_CONTROL_SERVICE, new BinderService());
@@ -320,7 +326,6 @@
}
}
-
private void registerContentObserver() {
ContentResolver resolver = getContext().getContentResolver();
String[] settings = new String[] {
@@ -330,7 +335,7 @@
Global.MHL_INPUT_SWITCHING_ENABLED,
Global.MHL_POWER_CHARGE_ENABLED
};
- for (String s: settings) {
+ for (String s : settings) {
resolver.registerContentObserver(Global.getUriFor(s), false, mSettingsObserver,
UserHandle.USER_ALL);
}
@@ -684,16 +689,16 @@
/**
* Called when a new hotplug event is issued.
*
- * @param portNo hdmi port number where hot plug event issued.
+ * @param portId hdmi port number where hot plug event issued.
* @param connected whether to be plugged in or not
*/
@ServiceThreadOnly
- void onHotplug(int portNo, boolean connected) {
+ void onHotplug(int portId, boolean connected) {
assertRunOnServiceThread();
for (HdmiCecLocalDevice device : mCecController.getLocalDeviceList()) {
- device.onHotplug(portNo, connected);
+ device.onHotplug(portId, connected);
}
- announceHotplugEvent(portNo, connected);
+ announceHotplugEvent(portId, connected);
}
/**
@@ -794,10 +799,15 @@
HdmiMhlLocalDevice device = mMhlController.removeLocalDevice(portId);
if (device != null) {
device.onDeviceRemoved();
+ // There is no explicit event for device removal unlike capability register event
+ // used for device addition . Hence we remove the device on hotplug event.
+ invokeDeviceEventListeners(device.getInfo(), DEVICE_EVENT_REMOVE_DEVICE);
+ updateSafeMhlInput();
} else {
Slog.w(TAG, "No device to remove:[portId=" + portId);
}
}
+ announceHotplugEvent(portId, connected);
}
@ServiceThreadOnly
@@ -824,18 +834,45 @@
}
@ServiceThreadOnly
- void handleCapabilityRegisterChanged(int portId, int adopterId, int deviceId) {
+ void handleMhlCapabilityRegisterChanged(int portId, int adopterId, int deviceId) {
assertRunOnServiceThread();
HdmiMhlLocalDevice device = mMhlController.getLocalDevice(portId);
- // Hot plug event should be called before capability register change event.
+
+ // Hotplug event should already have been called before capability register change event.
if (device != null) {
device.setCapabilityRegister(adopterId, deviceId);
+ invokeDeviceEventListeners(device.getInfo(), DEVICE_EVENT_ADD_DEVICE);
+ updateSafeMhlInput();
} else {
Slog.w(TAG, "No mhl device exists for capability register change event[portId:"
+ portId + ", adopterId:" + adopterId + ", deviceId:" + deviceId + "]");
}
}
+ @ServiceThreadOnly
+ private void updateSafeMhlInput() {
+ assertRunOnServiceThread();
+ List<HdmiDeviceInfo> inputs = Collections.emptyList();
+ SparseArray<HdmiMhlLocalDevice> devices = mMhlController.getAllLocalDevices();
+ for (int i = 0; i < devices.size(); ++i) {
+ HdmiMhlLocalDevice device = devices.valueAt(i);
+ HdmiDeviceInfo info = device.getInfo();
+ if (info != null) {
+ if (inputs.isEmpty()) {
+ inputs = new ArrayList<>();
+ }
+ inputs.add(device.getInfo());
+ }
+ }
+ synchronized (mLock) {
+ mMhlDevices = inputs;
+ }
+ }
+
+ private List<HdmiDeviceInfo> getMhlDevicesLocked() {
+ return mMhlDevices;
+ }
+
// Record class that monitors the event of the caller of being killed. Used to clean up
// the listener list and record list accordingly.
private final class HotplugEventListenerRecord implements IBinder.DeathRecipient {
@@ -1139,10 +1176,12 @@
// No need to hold the lock for obtaining TV device as the local device instance
// is preserved while the HDMI control is enabled.
HdmiCecLocalDeviceTv tv = tv();
- if (tv == null) {
- return Collections.emptyList();
+ synchronized (mLock) {
+ List<HdmiDeviceInfo> cecDevices = (tv == null)
+ ? Collections.<HdmiDeviceInfo>emptyList()
+ : tv.getSafeExternalInputsLocked();
+ return HdmiUtils.mergeToUnmodifiableList(cecDevices, getMhlDevicesLocked());
}
- return tv.getSafeExternalInputs();
}
@Override
diff --git a/services/core/java/com/android/server/hdmi/HdmiUtils.java b/services/core/java/com/android/server/hdmi/HdmiUtils.java
index 23f19ff..22a519b 100644
--- a/services/core/java/com/android/server/hdmi/HdmiUtils.java
+++ b/services/core/java/com/android/server/hdmi/HdmiUtils.java
@@ -206,6 +206,22 @@
return list;
}
+ static <T> List<T> mergeToUnmodifiableList(List<T> a, List<T> b) {
+ if (a.isEmpty() && b.isEmpty()) {
+ return Collections.emptyList();
+ }
+ if (a.isEmpty()) {
+ return Collections.unmodifiableList(b);
+ }
+ if (b.isEmpty()) {
+ return Collections.unmodifiableList(a);
+ }
+ List<T> newList = new ArrayList<>();
+ newList.addAll(a);
+ newList.addAll(b);
+ return Collections.unmodifiableList(newList);
+ }
+
/**
* See if the new path is affecting the active path.
*
diff --git a/services/core/java/com/android/server/hdmi/SendKeyAction.java b/services/core/java/com/android/server/hdmi/SendKeyAction.java
index 9f09eb4..ed978e0 100644
--- a/services/core/java/com/android/server/hdmi/SendKeyAction.java
+++ b/services/core/java/com/android/server/hdmi/SendKeyAction.java
@@ -109,12 +109,12 @@
}
private void sendKeyDown(int keycode) {
- byte[] keycodeAndParam = getCecKeycodeAndParam(keycode);
- if (keycodeAndParam == null) {
+ int cecKeycode = HdmiCecKeycode.androidKeyToCecKey(keycode);
+ if (cecKeycode == HdmiCecKeycode.UNSUPPORTED_KEYCODE) {
return;
}
sendCommand(HdmiCecMessageBuilder.buildUserControlPressed(getSourceAddress(),
- mTargetAddress, keycodeAndParam));
+ mTargetAddress, new byte[] { (byte) (cecKeycode & 0xFF) }));
}
private void sendKeyUp() {
@@ -141,13 +141,4 @@
sendKeyDown(mLastKeycode);
addTimer(mState, IRT_MS);
}
-
- // Converts the Android key code to corresponding CEC key code definition. Those CEC keys
- // with additional parameters should be mapped from individual Android key code. 'Select
- // Broadcast' with the parameter 'cable', for instance, shall have its counterpart such as
- // KeyEvent.KEYCODE_TV_BROADCAST_CABLE.
- // The return byte array contains both UI command (keycode) and optional parameter.
- private byte[] getCecKeycodeAndParam(int keycode) {
- return HdmiCecKeycode.androidKeyToCecKey(keycode);
- }
}
diff --git a/services/core/java/com/android/server/net/IpConfigStore.java b/services/core/java/com/android/server/net/IpConfigStore.java
index 907eeb2..857b9e9 100644
--- a/services/core/java/com/android/server/net/IpConfigStore.java
+++ b/services/core/java/com/android/server/net/IpConfigStore.java
@@ -20,10 +20,10 @@
import android.net.IpConfiguration.IpAssignment;
import android.net.IpConfiguration.ProxySettings;
import android.net.LinkAddress;
-import android.net.LinkProperties;
import android.net.NetworkUtils;
import android.net.ProxyInfo;
import android.net.RouteInfo;
+import android.net.StaticIpConfiguration;
import android.os.Handler;
import android.os.HandlerThread;
import android.text.TextUtils;
@@ -41,6 +41,7 @@
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.InetAddress;
+import java.net.Inet4Address;
import java.util.Map;
public class IpConfigStore {
@@ -69,40 +70,32 @@
}
private boolean writeConfig(DataOutputStream out, int configKey,
- IpConfiguration config) throws IOException {
+ IpConfiguration config) throws IOException {
boolean written = false;
try {
- LinkProperties linkProperties = config.linkProperties;
switch (config.ipAssignment) {
case STATIC:
out.writeUTF(IP_ASSIGNMENT_KEY);
out.writeUTF(config.ipAssignment.toString());
- for (LinkAddress linkAddr : linkProperties.getLinkAddresses()) {
- out.writeUTF(LINK_ADDRESS_KEY);
- out.writeUTF(linkAddr.getAddress().getHostAddress());
- out.writeInt(linkAddr.getPrefixLength());
- }
- for (RouteInfo route : linkProperties.getRoutes()) {
- out.writeUTF(GATEWAY_KEY);
- LinkAddress dest = route.getDestinationLinkAddress();
- if (dest != null) {
- out.writeInt(1);
- out.writeUTF(dest.getAddress().getHostAddress());
- out.writeInt(dest.getPrefixLength());
- } else {
- out.writeInt(0);
+ StaticIpConfiguration staticIpConfiguration = config.staticIpConfiguration;
+ if (staticIpConfiguration != null) {
+ if (staticIpConfiguration.ipAddress != null) {
+ LinkAddress ipAddress = staticIpConfiguration.ipAddress;
+ out.writeUTF(LINK_ADDRESS_KEY);
+ out.writeUTF(ipAddress.getAddress().getHostAddress());
+ out.writeInt(ipAddress.getPrefixLength());
}
- if (route.getGateway() != null) {
- out.writeInt(1);
- out.writeUTF(route.getGateway().getHostAddress());
- } else {
- out.writeInt(0);
+ if (staticIpConfiguration.gateway != null) {
+ out.writeUTF(GATEWAY_KEY);
+ out.writeInt(0); // Default route.
+ out.writeInt(1); // Have a gateway.
+ out.writeUTF(staticIpConfiguration.gateway.getHostAddress());
}
- }
- for (InetAddress inetAddr : linkProperties.getDnsServers()) {
- out.writeUTF(DNS_KEY);
- out.writeUTF(inetAddr.getHostAddress());
+ for (InetAddress inetAddr : staticIpConfiguration.dnsServers) {
+ out.writeUTF(DNS_KEY);
+ out.writeUTF(inetAddr.getHostAddress());
+ }
}
written = true;
break;
@@ -121,7 +114,7 @@
switch (config.proxySettings) {
case STATIC:
- ProxyInfo proxyProperties = linkProperties.getHttpProxy();
+ ProxyInfo proxyProperties = config.httpProxy;
String exclusionList = proxyProperties.getExclusionListAsString();
out.writeUTF(PROXY_SETTINGS_KEY);
out.writeUTF(config.proxySettings.toString());
@@ -134,7 +127,7 @@
written = true;
break;
case PAC:
- ProxyInfo proxyPacProperties = linkProperties.getHttpProxy();
+ ProxyInfo proxyPacProperties = config.httpProxy;
out.writeUTF(PROXY_SETTINGS_KEY);
out.writeUTF(config.proxySettings.toString());
out.writeUTF(PROXY_PAC_FILE);
@@ -159,7 +152,7 @@
out.writeInt(configKey);
}
} catch (NullPointerException e) {
- loge("Failure in writing " + config.linkProperties + e);
+ loge("Failure in writing " + config + e);
}
out.writeUTF(EOS);
@@ -196,7 +189,7 @@
// Default is DHCP with no proxy
IpAssignment ipAssignment = IpAssignment.DHCP;
ProxySettings proxySettings = ProxySettings.NONE;
- LinkProperties linkProperties = new LinkProperties();
+ StaticIpConfiguration staticIpConfiguration = new StaticIpConfiguration();
String proxyHost = null;
String pacFileUrl = null;
int proxyPort = -1;
@@ -213,13 +206,23 @@
} else if (key.equals(LINK_ADDRESS_KEY)) {
LinkAddress linkAddr = new LinkAddress(
NetworkUtils.numericToInetAddress(in.readUTF()), in.readInt());
- linkProperties.addLinkAddress(linkAddr);
+ if (linkAddr.getAddress() instanceof Inet4Address &&
+ staticIpConfiguration.ipAddress == null) {
+ staticIpConfiguration.ipAddress = linkAddr;
+ } else {
+ loge("Non-IPv4 or duplicate address: " + linkAddr);
+ }
} else if (key.equals(GATEWAY_KEY)) {
LinkAddress dest = null;
InetAddress gateway = null;
if (version == 1) {
// only supported default gateways - leave the dest/prefix empty
gateway = NetworkUtils.numericToInetAddress(in.readUTF());
+ if (staticIpConfiguration.gateway == null) {
+ staticIpConfiguration.gateway = gateway;
+ } else {
+ loge("Duplicate gateway: " + gateway.getHostAddress());
+ }
} else {
if (in.readInt() == 1) {
dest = new LinkAddress(
@@ -229,10 +232,16 @@
if (in.readInt() == 1) {
gateway = NetworkUtils.numericToInetAddress(in.readUTF());
}
+ RouteInfo route = new RouteInfo(dest, gateway);
+ if (route.isIPv4Default() &&
+ staticIpConfiguration.gateway == null) {
+ staticIpConfiguration.gateway = gateway;
+ } else {
+ loge("Non-IPv4 default or duplicate route: " + route);
+ }
}
- linkProperties.addRoute(new RouteInfo(dest, gateway));
} else if (key.equals(DNS_KEY)) {
- linkProperties.addDnsServer(
+ staticIpConfiguration.dnsServers.add(
NetworkUtils.numericToInetAddress(in.readUTF()));
} else if (key.equals(PROXY_SETTINGS_KEY)) {
proxySettings = ProxySettings.valueOf(in.readUTF());
@@ -258,9 +267,11 @@
IpConfiguration config = new IpConfiguration();
networks.put(id, config);
- config.linkProperties = linkProperties;
switch (ipAssignment) {
case STATIC:
+ config.staticIpConfiguration = staticIpConfiguration;
+ config.ipAssignment = ipAssignment;
+ break;
case DHCP:
config.ipAssignment = ipAssignment;
break;
@@ -276,16 +287,15 @@
switch (proxySettings) {
case STATIC:
- config.proxySettings = proxySettings;
- ProxyInfo ProxyInfo =
+ ProxyInfo proxyInfo =
new ProxyInfo(proxyHost, proxyPort, exclusionList);
- linkProperties.setHttpProxy(ProxyInfo);
+ config.proxySettings = proxySettings;
+ config.httpProxy = proxyInfo;
break;
case PAC:
+ ProxyInfo proxyPacProperties = new ProxyInfo(pacFileUrl);
config.proxySettings = proxySettings;
- ProxyInfo proxyPacProperties =
- new ProxyInfo(pacFileUrl);
- linkProperties.setHttpProxy(proxyPacProperties);
+ config.httpProxy = proxyPacProperties;
break;
case NONE:
config.proxySettings = proxySettings;
diff --git a/services/core/java/com/android/server/notification/NotificationDelegate.java b/services/core/java/com/android/server/notification/NotificationDelegate.java
index 1b59f52..97f0a1e 100644
--- a/services/core/java/com/android/server/notification/NotificationDelegate.java
+++ b/services/core/java/com/android/server/notification/NotificationDelegate.java
@@ -16,8 +16,6 @@
package com.android.server.notification;
-import android.os.IBinder;
-
public interface NotificationDelegate {
void onSetDisabled(int status);
void onClearAll(int callingUid, int callingPid, int userId);
@@ -29,7 +27,6 @@
int uid, int initialPid, String message, int userId);
void onPanelRevealed();
void onPanelHidden();
- boolean allowDisable(int what, IBinder token, String pkg);
void onNotificationVisibilityChanged(
String[] newlyVisibleKeys, String[] noLongerVisibleKeys);
void onNotificationExpansionChanged(String key, boolean userAction, boolean expanded);
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index f2ac963..7117933 100644
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -29,7 +29,6 @@
import android.app.INotificationManager;
import android.app.ITransientNotification;
import android.app.Notification;
-import android.app.Notification.Builder;
import android.app.PendingIntent;
import android.app.StatusBarManager;
import android.content.BroadcastReceiver;
@@ -50,7 +49,6 @@
import android.media.IRingtonePlayer;
import android.net.Uri;
import android.os.Binder;
-import android.os.Build;
import android.os.Environment;
import android.os.Handler;
import android.os.HandlerThread;
@@ -585,11 +583,6 @@
}
@Override
- public boolean allowDisable(int what, IBinder token, String pkg) {
- return mZenModeHelper.allowDisable(what, token, pkg);
- }
-
- @Override
public void onNotificationVisibilityChanged(
String[] newlyVisibleKeys, String[] noLongerVisibleKeys) {
// Using ';' as separator since eventlogs uses ',' to separate
diff --git a/services/core/java/com/android/server/notification/ZenLog.java b/services/core/java/com/android/server/notification/ZenLog.java
index 525f5f8..f84409e 100644
--- a/services/core/java/com/android/server/notification/ZenLog.java
+++ b/services/core/java/com/android/server/notification/ZenLog.java
@@ -30,10 +30,7 @@
import java.io.PrintWriter;
import java.text.SimpleDateFormat;
-import java.util.Arrays;
import java.util.Date;
-import java.util.HashSet;
-import java.util.Set;
public class ZenLog {
private static final String TAG = "ZenLog";
@@ -45,10 +42,6 @@
private static final String[] MSGS = new String[SIZE];
private static final SimpleDateFormat FORMAT = new SimpleDateFormat("MM-dd HH:mm:ss.SSS");
- private static final Set<String> SYSTEM_PACKAGES = new HashSet<String>(Arrays.asList(
- "android",
- "com.android.systemui"
- ));
private static final int TYPE_INTERCEPTED = 1;
private static final int TYPE_ALLOW_DISABLE = 2;
@@ -76,11 +69,6 @@
append(TYPE_NOT_INTERCEPTED, record.getKey() + "," + reason);
}
- public static void traceAllowDisable(String pkg, boolean allowDisable, String reason) {
- if (SYSTEM_PACKAGES.contains(pkg)) return;
- append(TYPE_ALLOW_DISABLE, allowDisable + "," + pkg + "," + reason);
- }
-
public static void traceSetRingerMode(int ringerMode) {
append(TYPE_SET_RINGER_MODE, ringerModeToString(ringerMode));
}
diff --git a/services/core/java/com/android/server/notification/ZenModeHelper.java b/services/core/java/com/android/server/notification/ZenModeHelper.java
index 758f334..0b93690 100644
--- a/services/core/java/com/android/server/notification/ZenModeHelper.java
+++ b/services/core/java/com/android/server/notification/ZenModeHelper.java
@@ -35,7 +35,6 @@
import android.media.AudioManager;
import android.net.Uri;
import android.os.Handler;
-import android.os.IBinder;
import android.os.UserHandle;
import android.provider.Settings.Global;
import android.provider.Settings.Secure;
@@ -265,18 +264,6 @@
dispatchOnZenModeChanged();
}
- public boolean allowDisable(int what, IBinder token, String pkg) {
- // TODO(cwren): delete this API before the next release. Bug:15344099
- boolean allowDisable = true;
- String reason = null;
- if (isDefaultPhoneApp(pkg)) {
- allowDisable = mZenMode == Global.ZEN_MODE_OFF || mConfig.allowCalls;
- reason = mZenMode == Global.ZEN_MODE_OFF ? "zenOff" : "allowCalls";
- }
- ZenLog.traceAllowDisable(pkg, allowDisable, reason);
- return allowDisable;
- }
-
public void dump(PrintWriter pw, String prefix) {
pw.print(prefix); pw.print("mZenMode=");
pw.println(Global.zenModeToString(mZenMode));
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index b5c8cb4..f47e64f 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -3292,6 +3292,7 @@
intent, resolvedType, flags, userId);
if (resolveInfo != null) {
result.add(resolveInfo);
+ Collections.sort(result, mResolvePrioritySorter);
}
return result;
}
diff --git a/services/core/java/com/android/server/statusbar/StatusBarManagerService.java b/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
index 297dacf..f85e2d9 100644
--- a/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
+++ b/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
@@ -22,7 +22,6 @@
import android.os.IBinder;
import android.os.RemoteException;
import android.os.UserHandle;
-import android.service.notification.StatusBarNotification;
import android.content.Context;
import android.content.pm.PackageManager;
import android.content.res.Resources;
@@ -39,9 +38,7 @@
import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.util.ArrayList;
-import java.util.HashMap;
import java.util.List;
-import java.util.Map;
/**
@@ -187,10 +184,6 @@
@Override
public void disable(int what, IBinder token, String pkg) {
- if (!mNotificationDelegate.allowDisable(what, token, pkg)) {
- if (SPEW) Slog.d(TAG, "Blocking disable request from " + pkg);
- return;
- }
disableInternal(mCurrentUserId, what, token, pkg);
}
diff --git a/services/core/java/com/android/server/tv/TvInputManagerService.java b/services/core/java/com/android/server/tv/TvInputManagerService.java
index 0a73a34..a084cab 100644
--- a/services/core/java/com/android/server/tv/TvInputManagerService.java
+++ b/services/core/java/com/android/server/tv/TvInputManagerService.java
@@ -691,6 +691,10 @@
private void releaseSessionLocked(IBinder sessionToken, int callingUid, int userId) {
SessionState sessionState = getSessionStateLocked(sessionToken, callingUid, userId);
if (sessionState.mSession != null) {
+ UserState userState = getUserStateLocked(userId);
+ if (sessionToken == userState.mainSessionToken) {
+ setMainLocked(sessionToken, false, callingUid, userId);
+ }
try {
sessionState.mSession.release();
} catch (RemoteException e) {
@@ -704,6 +708,9 @@
private void removeSessionStateLocked(IBinder sessionToken, int userId) {
UserState userState = getUserStateLocked(userId);
if (sessionToken == userState.mainSessionToken) {
+ if (DEBUG) {
+ Slog.d(TAG, "mainSessionToken=null");
+ }
userState.mainSessionToken = null;
}
@@ -740,6 +747,25 @@
mWatchLogHandler.obtainMessage(WatchLogHandler.MSG_LOG_WATCH_END, args).sendToTarget();
}
+ private void setMainLocked(IBinder sessionToken, boolean isMain, int callingUid, int userId) {
+ SessionState sessionState = getSessionStateLocked(sessionToken, callingUid, userId);
+ if (sessionState.mHardwareSessionToken != null) {
+ sessionState = getSessionStateLocked(sessionState.mHardwareSessionToken,
+ Process.SYSTEM_UID, userId);
+ }
+ ServiceState serviceState = getServiceStateLocked(sessionState.mInfo.getComponent(),
+ userId);
+ if (!serviceState.mIsHardware) {
+ return;
+ }
+ ITvInputSession session = getSessionLocked(sessionState);
+ try {
+ session.setMain(isMain);
+ } catch (RemoteException e) {
+ Slog.e(TAG, "error in setMain", e);
+ }
+ }
+
private void notifyInputAddedLocked(UserState userState, String inputId) {
if (DEBUG) {
Slog.d(TAG, "notifyInputAdded: inputId = " + inputId);
@@ -1050,6 +1076,9 @@
@Override
public void releaseSession(IBinder sessionToken, int userId) {
+ if (DEBUG) {
+ Slog.d(TAG, "releaseSession(): " + sessionToken);
+ }
final int callingUid = Binder.getCallingUid();
final int resolvedUserId = resolveCallingUserId(Binder.getCallingPid(), callingUid,
userId, "releaseSession");
@@ -1065,6 +1094,9 @@
@Override
public void setMainSession(IBinder sessionToken, int userId) {
+ if (DEBUG) {
+ Slog.d(TAG, "setMainSession(): " + sessionToken);
+ }
final int callingUid = Binder.getCallingUid();
final int resolvedUserId = resolveCallingUserId(Binder.getCallingPid(), callingUid,
userId, "setMainSession");
@@ -1075,50 +1107,19 @@
if (userState.mainSessionToken == sessionToken) {
return;
}
-
- SessionState newMainSessionState = getSessionStateLocked(
- sessionToken, callingUid, resolvedUserId);
- if (newMainSessionState.mHardwareSessionToken != null) {
- newMainSessionState = getSessionStateLocked(
- newMainSessionState.mHardwareSessionToken,
- Process.SYSTEM_UID, resolvedUserId);
+ if (DEBUG) {
+ Slog.d(TAG, "mainSessionToken=" + sessionToken);
}
- ServiceState newMainServiceState = getServiceStateLocked(
- newMainSessionState.mInfo.getComponent(), resolvedUserId);
- ITvInputSession newMainSession = getSessionLocked(newMainSessionState);
-
- ServiceState oldMainServiceState = null;
- ITvInputSession oldMainSession = null;
- if (userState.mainSessionToken != null) {
- SessionState oldMainSessionState = getSessionStateLocked(
- userState.mainSessionToken, Process.SYSTEM_UID, resolvedUserId);
- if (oldMainSessionState.mHardwareSessionToken != null) {
- oldMainSessionState = getSessionStateLocked(
- oldMainSessionState.mHardwareSessionToken,
- Process.SYSTEM_UID, resolvedUserId);
- }
- oldMainServiceState = getServiceStateLocked(
- oldMainSessionState.mInfo.getComponent(), resolvedUserId);
- oldMainSession = getSessionLocked(oldMainSessionState);
- }
-
+ IBinder oldMainSessionToken = userState.mainSessionToken;
userState.mainSessionToken = sessionToken;
// Inform the new main session first.
- // See {@link TvInputService#onSetMainSession}.
- if (newMainServiceState.mIsHardware) {
- try {
- newMainSession.setMainSession(true);
- } catch (RemoteException e) {
- Slog.e(TAG, "error in setMainSession", e);
- }
+ // See {@link TvInputService.Session#onSetMain}.
+ if (sessionToken != null) {
+ setMainLocked(sessionToken, true, callingUid, userId);
}
- if (oldMainSession != null && oldMainServiceState.mIsHardware) {
- try {
- oldMainSession.setMainSession(false);
- } catch (RemoteException e) {
- Slog.e(TAG, "error in setMainSession", e);
- }
+ if (oldMainSessionToken != null) {
+ setMainLocked(oldMainSessionToken, false, Process.SYSTEM_UID, userId);
}
}
} finally {
diff --git a/telecomm/java/android/telecomm/InCallService.java b/telecomm/java/android/telecomm/InCallService.java
index de05d1c..5795e0e 100644
--- a/telecomm/java/android/telecomm/InCallService.java
+++ b/telecomm/java/android/telecomm/InCallService.java
@@ -16,6 +16,7 @@
package android.telecomm;
+import android.annotation.SdkConstant;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Intent;
@@ -39,6 +40,13 @@
* {@hide}
*/
public abstract class InCallService extends Service {
+
+ /**
+ * The {@link Intent} that must be declared as handled by the service.
+ */
+ @SdkConstant(SdkConstant.SdkConstantType.SERVICE_ACTION)
+ public static final String SERVICE_INTERFACE = "android.telecomm.InCallService";
+
private static final int MSG_SET_IN_CALL_ADAPTER = 1;
private static final int MSG_ADD_CALL = 2;
private static final int MSG_UPDATE_CALL = 3;
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index c50110a..d4f8362 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -2459,7 +2459,7 @@
* @param filePath
* @return The APDU response.
*/
- byte[] iccExchangeSimIO(int fileID, int command, int p1, int p2, int p3,
+ public byte[] iccExchangeSimIO(int fileID, int command, int p1, int p2, int p3,
String filePath) {
try {
return getITelephony().iccExchangeSimIO(fileID, command, p1, p2,
diff --git a/wifi/java/android/net/wifi/WifiConfiguration.java b/wifi/java/android/net/wifi/WifiConfiguration.java
index 3c37b94..ac2a176 100644
--- a/wifi/java/android/net/wifi/WifiConfiguration.java
+++ b/wifi/java/android/net/wifi/WifiConfiguration.java
@@ -21,7 +21,7 @@
import android.net.IpConfiguration.ProxySettings;
import android.net.IpConfiguration.IpAssignment;
import android.net.ProxyInfo;
-import android.net.LinkProperties;
+import android.net.StaticIpConfiguration;
import android.os.Parcel;
import android.os.Parcelable;
import android.text.TextUtils;
@@ -1096,13 +1096,13 @@
}
/** @hide */
- public LinkProperties getLinkProperties() {
- return mIpConfiguration.linkProperties;
+ public StaticIpConfiguration getStaticIpConfiguration() {
+ return mIpConfiguration.getStaticIpConfiguration();
}
/** @hide */
- public void setLinkProperties(LinkProperties linkProperties) {
- mIpConfiguration.linkProperties = linkProperties;
+ public void setStaticIpConfiguration(StaticIpConfiguration staticIpConfiguration) {
+ mIpConfiguration.setStaticIpConfiguration(staticIpConfiguration);
}
/** @hide */
@@ -1126,9 +1126,19 @@
}
/** @hide */
+ public ProxyInfo getHttpProxy() {
+ return mIpConfiguration.httpProxy;
+ }
+
+ /** @hide */
+ public void setHttpProxy(ProxyInfo httpProxy) {
+ mIpConfiguration.httpProxy = httpProxy;
+ }
+
+ /** @hide */
public void setProxy(ProxySettings settings, ProxyInfo proxy) {
mIpConfiguration.proxySettings = settings;
- mIpConfiguration.linkProperties.setHttpProxy(proxy);
+ mIpConfiguration.httpProxy = proxy;
}
/** Implement the Parcelable interface {@hide} */