diff options
137 files changed, 2369 insertions, 1549 deletions
@@ -156,7 +156,7 @@ LOCAL_SRC_FILES += \ core/java/android/hardware/hdmi/IHdmiDeviceEventListener.aidl \ core/java/android/hardware/hdmi/IHdmiHotplugEventListener.aidl \ core/java/android/hardware/hdmi/IHdmiInputChangeListener.aidl \ - core/java/android/hardware/hdmi/IHdmiMhlScratchpadCommandListener.aidl \ + core/java/android/hardware/hdmi/IHdmiMhlVendorCommandListener.aidl \ core/java/android/hardware/hdmi/IHdmiRecordListener.aidl \ core/java/android/hardware/hdmi/IHdmiSystemAudioModeChangeListener.aidl \ core/java/android/hardware/hdmi/IHdmiVendorCommandListener.aidl \ diff --git a/api/current.txt b/api/current.txt index 6135550..9686baf 100644 --- a/api/current.txt +++ b/api/current.txt @@ -1429,6 +1429,7 @@ package android { field public static final int windowActionBar = 16843469; // 0x10102cd field public static final int windowActionBarOverlay = 16843492; // 0x10102e4 field public static final int windowActionModeOverlay = 16843485; // 0x10102dd + field public static final int windowActivityTransitions = 16843982; // 0x10104ce field public static final int windowAllowEnterTransitionOverlap = 16843836; // 0x101043c field public static final int windowAllowReturnTransitionOverlap = 16843835; // 0x101043b field public static final int windowAnimationStyle = 16842926; // 0x10100ae @@ -2549,6 +2550,7 @@ package android { field public static final int Widget_Material_Light_CompoundButton_CheckBox = 16974504; // 0x10302a8 field public static final int Widget_Material_Light_CompoundButton_RadioButton = 16974505; // 0x10302a9 field public static final int Widget_Material_Light_CompoundButton_Star = 16974506; // 0x10302aa + field public static final int Widget_Material_Light_DatePicker = 16974578; // 0x10302f2 field public static final int Widget_Material_Light_DropDownItem = 16974507; // 0x10302ab field public static final int Widget_Material_Light_DropDownItem_Spinner = 16974508; // 0x10302ac field public static final int Widget_Material_Light_EditText = 16974509; // 0x10302ad @@ -2586,6 +2588,7 @@ package android { field public static final int Widget_Material_Light_TabWidget = 16974539; // 0x10302cb field public static final int Widget_Material_Light_TextView = 16974540; // 0x10302cc field public static final int Widget_Material_Light_TextView_SpinnerItem = 16974541; // 0x10302cd + field public static final int Widget_Material_Light_TimePicker = 16974577; // 0x10302f1 field public static final int Widget_Material_Light_WebTextView = 16974542; // 0x10302ce field public static final int Widget_Material_Light_WebView = 16974543; // 0x10302cf field public static final int Widget_Material_ListPopupWindow = 16974455; // 0x1030277 @@ -2614,6 +2617,7 @@ package android { field public static final int Widget_Material_TabWidget = 16974476; // 0x103028c field public static final int Widget_Material_TextView = 16974477; // 0x103028d field public static final int Widget_Material_TextView_SpinnerItem = 16974478; // 0x103028e + field public static final int Widget_Material_TimePicker = 16974576; // 0x10302f0 field public static final int Widget_Material_Toolbar = 16974479; // 0x103028f field public static final int Widget_Material_Toolbar_Button_Navigation = 16974480; // 0x1030290 field public static final int Widget_Material_WebTextView = 16974481; // 0x1030291 @@ -5402,7 +5406,7 @@ package android.app.admin { field public static final java.lang.String ACTION_PASSWORD_EXPIRING = "android.app.action.ACTION_PASSWORD_EXPIRING"; field public static final java.lang.String ACTION_PASSWORD_FAILED = "android.app.action.ACTION_PASSWORD_FAILED"; field public static final java.lang.String ACTION_PASSWORD_SUCCEEDED = "android.app.action.ACTION_PASSWORD_SUCCEEDED"; - field public static final java.lang.String ACTION_PROFILE_PROVISIONING_COMPLETE = "android.app.action.ACTION_PROFILE_PROVISIONING_COMPLETE"; + field public static final java.lang.String ACTION_PROFILE_PROVISIONING_COMPLETE = "android.app.action.PROFILE_PROVISIONING_COMPLETE"; field public static final java.lang.String DEVICE_ADMIN_META_DATA = "android.app.device_admin"; field public static final java.lang.String EXTRA_DISABLE_WARNING = "android.app.extra.DISABLE_WARNING"; field public static final java.lang.String EXTRA_LOCK_TASK_PACKAGE = "android.app.extra.LOCK_TASK_PACKAGE"; @@ -5518,6 +5522,7 @@ package android.app.admin { field public static final java.lang.String EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_DOWNLOAD_COOKIE_HEADER = "android.app.extra.PROVISIONING_DEVICE_ADMIN_PACKAGE_DOWNLOAD_COOKIE_HEADER"; field public static final java.lang.String EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_DOWNLOAD_LOCATION = "android.app.extra.PROVISIONING_DEVICE_ADMIN_PACKAGE_DOWNLOAD_LOCATION"; field public static final java.lang.String EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_NAME = "android.app.extra.PROVISIONING_DEVICE_ADMIN_PACKAGE_NAME"; + field public static final java.lang.String EXTRA_PROVISIONING_EMAIL_ADDRESS = "android.app.extra.PROVISIONING_EMAIL_ADDRESS"; field public static final java.lang.String EXTRA_PROVISIONING_LOCALE = "android.app.extra.PROVISIONING_LOCALE"; field public static final java.lang.String EXTRA_PROVISIONING_LOCAL_TIME = "android.app.extra.PROVISIONING_LOCAL_TIME"; field public static final java.lang.String EXTRA_PROVISIONING_TIME_ZONE = "android.app.extra.PROVISIONING_TIME_ZONE"; @@ -5539,7 +5544,6 @@ package android.app.admin { field public static final int KEYGUARD_DISABLE_TRUST_AGENTS = 16; // 0x10 field public static final int KEYGUARD_DISABLE_UNREDACTED_NOTIFICATIONS = 8; // 0x8 field public static final int KEYGUARD_DISABLE_WIDGETS_ALL = 1; // 0x1 - field public static final java.lang.String KEY_PROVISIONING_EMAIL_ADDRESS = "android.app.key.PROVISIONING_EMAIL_ADDRESS"; field public static final java.lang.String MIME_TYPE_PROVISIONING_NFC = "application/com.android.managedprovisioning"; field public static final int PASSWORD_QUALITY_ALPHABETIC = 262144; // 0x40000 field public static final int PASSWORD_QUALITY_ALPHANUMERIC = 327680; // 0x50000 @@ -6390,7 +6394,6 @@ package android.bluetooth { method public void onCharacteristicChanged(android.bluetooth.BluetoothGatt, android.bluetooth.BluetoothGattCharacteristic); method public void onCharacteristicRead(android.bluetooth.BluetoothGatt, android.bluetooth.BluetoothGattCharacteristic, int); method public void onCharacteristicWrite(android.bluetooth.BluetoothGatt, android.bluetooth.BluetoothGattCharacteristic, int); - method public void onConnectionCongested(android.bluetooth.BluetoothGatt, boolean); method public void onConnectionStateChange(android.bluetooth.BluetoothGatt, int, int); method public void onDescriptorRead(android.bluetooth.BluetoothGatt, android.bluetooth.BluetoothGattDescriptor, int); method public void onDescriptorWrite(android.bluetooth.BluetoothGatt, android.bluetooth.BluetoothGattDescriptor, int); @@ -6490,7 +6493,6 @@ package android.bluetooth { ctor public BluetoothGattServerCallback(); method public void onCharacteristicReadRequest(android.bluetooth.BluetoothDevice, int, int, android.bluetooth.BluetoothGattCharacteristic); method public void onCharacteristicWriteRequest(android.bluetooth.BluetoothDevice, int, android.bluetooth.BluetoothGattCharacteristic, boolean, boolean, int, byte[]); - method public void onConnectionCongested(android.bluetooth.BluetoothDevice, boolean); method public void onConnectionStateChange(android.bluetooth.BluetoothDevice, int, int); method public void onDescriptorReadRequest(android.bluetooth.BluetoothDevice, int, int, android.bluetooth.BluetoothGattDescriptor); method public void onDescriptorWriteRequest(android.bluetooth.BluetoothDevice, int, android.bluetooth.BluetoothGattDescriptor, boolean, boolean, int, byte[]); @@ -8620,13 +8622,11 @@ package android.content.pm { } public class LauncherApps { - method public void addCallback(android.content.pm.LauncherApps.Callback); 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 isPackageEnabled(java.lang.String, android.os.UserHandle); method public void registerCallback(android.content.pm.LauncherApps.Callback); method public void registerCallback(android.content.pm.LauncherApps.Callback, android.os.Handler); - method public void removeCallback(android.content.pm.LauncherApps.Callback); method public android.content.pm.LauncherActivityInfo resolveActivity(android.content.Intent, android.os.UserHandle); 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); @@ -17537,14 +17537,12 @@ package android.net { public class VpnService extends android.app.Service { ctor public VpnService(); - method public boolean addAddress(java.net.InetAddress, int); method public android.os.IBinder onBind(android.content.Intent); method public void onRevoke(); method public static android.content.Intent prepare(android.content.Context); method public boolean protect(int); method public boolean protect(java.net.Socket); method public boolean protect(java.net.DatagramSocket); - method public boolean removeAddress(java.net.InetAddress, int); field public static final java.lang.String SERVICE_INTERFACE = "android.net.VpnService"; } @@ -22253,9 +22251,9 @@ package android.os { field public static final int ON_AFTER_RELEASE = 536870912; // 0x20000000 field public static final int PARTIAL_WAKE_LOCK = 1; // 0x1 field public static final int PROXIMITY_SCREEN_OFF_WAKE_LOCK = 32; // 0x20 + field public static final int RELEASE_FLAG_WAIT_FOR_NO_PROXIMITY = 1; // 0x1 field public static final deprecated int SCREEN_BRIGHT_WAKE_LOCK = 10; // 0xa field public static final deprecated int SCREEN_DIM_WAKE_LOCK = 6; // 0x6 - field public static final int WAIT_FOR_DISTANT_PROXIMITY = 1; // 0x1 } public final class PowerManager.WakeLock { @@ -28243,6 +28241,8 @@ package android.telecomm { method public static android.telecomm.Connection createCanceledConnection(); method public static android.telecomm.Connection createFailedConnection(int, java.lang.String); method public final void destroy(); + method public final android.net.Uri getAddress(); + method public final int getAddressPresentation(); method public final boolean getAudioModeIsVoip(); method public final android.telecomm.AudioState getAudioState(); method public final int getCallCapabilities(); @@ -28252,11 +28252,9 @@ package android.telecomm { method public final java.util.List<android.telecomm.Connection> getConferenceableConnections(); method public final int getDisconnectCause(); method public final java.lang.String getDisconnectMessage(); - method public final android.net.Uri getHandle(); - method public final int getHandlePresentation(); method public final int getState(); method public final android.telecomm.StatusHints getStatusHints(); - method public final boolean isRequestingRingback(); + method public final boolean isRingbackRequested(); method public void onAbort(); method public void onAnswer(); method public void onAudioStateChanged(android.telecomm.AudioState); @@ -28271,6 +28269,7 @@ package android.telecomm { method public void onStopDtmfTone(); method public void onUnhold(); method public final void setActive(); + method public final void setAddress(android.net.Uri, int); method public final void setAudioModeIsVoip(boolean); method public final void setCallCapabilities(int); method public final void setCallerDisplayName(java.lang.String, int); @@ -28278,12 +28277,11 @@ package android.telecomm { method public final void setConnectionService(android.telecomm.ConnectionService); method public final void setDialing(); method public final void setDisconnected(int, java.lang.String); - method public final void setHandle(android.net.Uri, int); method public final void setInitialized(); method public final void setInitializing(); method public final void setOnHold(); method public final void setPostDialWait(java.lang.String); - method public final void setRequestingRingback(boolean); + method public final void setRingbackRequested(boolean); method public final void setRinging(); method public final void setStatusHints(android.telecomm.StatusHints); method public static java.lang.String stateToString(int); @@ -28380,18 +28378,19 @@ package android.telecomm { public final class PhoneCapabilities { method public static java.lang.String toString(int); field public static final int ADD_CALL = 16; // 0x10 - field public static final int ALL = 255; // 0xff + field public static final int ALL = 12543; // 0x30ff + field public static final int DISCONNECT_FROM_CONFERENCE = 8192; // 0x2000 field public static final int HOLD = 1; // 0x1 field public static final int MANAGE_CONFERENCE = 128; // 0x80 field public static final int MERGE_CONFERENCE = 4; // 0x4 field public static final int MUTE = 64; // 0x40 field public static final int RESPOND_VIA_TEXT = 32; // 0x20 + field public static final int SEPARATE_FROM_CONFERENCE = 4096; // 0x1000 field public static final int SUPPORT_HOLD = 2; // 0x2 field public static final int SWAP_CONFERENCE = 8; // 0x8 } public final class RemoteConference { - method public final void addCallback(android.telecomm.RemoteConference.Callback); method public void disconnect(); method public final int getCallCapabilities(); method public final java.util.List<android.telecomm.RemoteConnection> getConnections(); @@ -28399,9 +28398,10 @@ package android.telecomm { method public java.lang.String getDisconnectMessage(); method public final int getState(); method public void hold(); - method public final void removeCallback(android.telecomm.RemoteConference.Callback); + method public final void registerCallback(android.telecomm.RemoteConference.Callback); method public void separate(android.telecomm.RemoteConnection); method public void unhold(); + method public final void unregisterCallback(android.telecomm.RemoteConference.Callback); } public static abstract class RemoteConference.Callback { @@ -28416,52 +28416,48 @@ package android.telecomm { public final class RemoteConnection { method public void abort(); - method public void addListener(android.telecomm.RemoteConnection.Listener); method public void answer(); method public void disconnect(); - method public boolean getAudioModeIsVoip(); + method public android.net.Uri getAddress(); + method public int getAddressPresentation(); method public int getCallCapabilities(); - method public java.lang.String getCallerDisplayName(); + method public java.lang.CharSequence getCallerDisplayName(); method public int getCallerDisplayNamePresentation(); - method public java.util.List<android.telecomm.RemoteConnection> getChildren(); method public android.telecomm.RemoteConference getConference(); method public java.util.List<android.telecomm.RemoteConnection> getConferenceableConnections(); method public int getDisconnectCauseCode(); method public java.lang.String getDisconnectCauseMessage(); method public int getFailureCode(); method public java.lang.String getFailureMessage(); - method public android.net.Uri getHandle(); - method public int getHandlePresentation(); - method public android.telecomm.RemoteConnection getParent(); method public int getState(); method public android.telecomm.StatusHints getStatusHints(); method public void hold(); - method public boolean isRequestingRingback(); + method public boolean isRingbackRequested(); + method public boolean isVoipAudioMode(); method public void playDtmfTone(char); method public void postDialContinue(boolean); + method public void registerCallback(android.telecomm.RemoteConnection.Callback); method public void reject(); - method public void removeListener(android.telecomm.RemoteConnection.Listener); method public void setAudioState(android.telecomm.AudioState); method public void stopDtmfTone(); method public void unhold(); + method public void unregisterCallback(android.telecomm.RemoteConnection.Callback); } - public static abstract class RemoteConnection.Listener { - ctor public RemoteConnection.Listener(); - method public void onAudioModeIsVoipChanged(android.telecomm.RemoteConnection, boolean); + public static abstract class RemoteConnection.Callback { + ctor public RemoteConnection.Callback(); + method public void onAddressChanged(android.telecomm.RemoteConnection, android.net.Uri, int); method public void onCallCapabilitiesChanged(android.telecomm.RemoteConnection, int); method public void onCallerDisplayNameChanged(android.telecomm.RemoteConnection, java.lang.String, int); - method public void onChildrenChanged(android.telecomm.RemoteConnection, java.util.List<android.telecomm.RemoteConnection>); method public void onConferenceChanged(android.telecomm.RemoteConnection, android.telecomm.RemoteConference); method public void onConferenceableConnectionsChanged(android.telecomm.RemoteConnection, java.util.List<android.telecomm.RemoteConnection>); method public void onDestroyed(android.telecomm.RemoteConnection); method public void onDisconnected(android.telecomm.RemoteConnection, int, java.lang.String); - method public void onHandleChanged(android.telecomm.RemoteConnection, android.net.Uri, int); - method public void onParentChanged(android.telecomm.RemoteConnection, android.telecomm.RemoteConnection); method public void onPostDialWait(android.telecomm.RemoteConnection, java.lang.String); - method public void onRequestingRingback(android.telecomm.RemoteConnection, boolean); + method public void onRingbackRequested(android.telecomm.RemoteConnection, boolean); method public void onStateChanged(android.telecomm.RemoteConnection, int); method public void onStatusHintsChanged(android.telecomm.RemoteConnection, android.telecomm.StatusHints); + method public void onVoipAudioChanged(android.telecomm.RemoteConnection, boolean); } public final class StatusHints implements android.os.Parcelable { @@ -28479,7 +28475,7 @@ package android.telecomm { public class TelecommManager { method public void addNewIncomingCall(android.telecomm.PhoneAccountHandle, android.os.Bundle); method public void cancelMissedCallsNotification(); - method public void clearAccounts(java.lang.String); + method public void clearAccounts(); method public android.telecomm.PhoneAccountHandle getConnectionManager(); method public android.telecomm.PhoneAccountHandle getDefaultOutgoingPhoneAccount(java.lang.String); method public java.util.List<android.telecomm.PhoneAccountHandle> getEnabledPhoneAccounts(); @@ -28493,6 +28489,8 @@ package android.telecomm { method public void unregisterPhoneAccount(android.telecomm.PhoneAccountHandle); field public static final java.lang.String ACTION_CHANGE_PHONE_ACCOUNTS = "android.telecomm.action.CHANGE_PHONE_ACCOUNTS"; field public static final java.lang.String ACTION_CONNECTION_SERVICE_CONFIGURE = "android.telecomm.action.CONNECTION_SERVICE_CONFIGURE"; + field public static final java.lang.String ACTION_PHONE_ACCOUNT_DISABLED = "android.telecom.action.PHONE_ACCOUNT_DISABLED"; + field public static final java.lang.String ACTION_PHONE_ACCOUNT_ENABLED = "android.telecom.action.PHONE_ACCOUNT_ENABLED"; field public static final java.lang.String ACTION_SHOW_CALL_SETTINGS = "android.telecomm.action.SHOW_CALL_SETTINGS"; field public static final char DTMF_CHARACTER_PAUSE = 44; // 0x002c ',' field public static final char DTMF_CHARACTER_WAIT = 59; // 0x003b ';' @@ -28502,6 +28500,8 @@ package android.telecomm { field public static final java.lang.String EXTRA_CONNECTION_SERVICE = "android.telecomm.extra.CONNECTION_SERVICE"; field public static final java.lang.String EXTRA_PHONE_ACCOUNT_HANDLE = "android.telecomm.extra.PHONE_ACCOUNT_HANDLE"; field public static final java.lang.String EXTRA_START_CALL_WITH_SPEAKERPHONE = "android.telecomm.extra.START_CALL_WITH_SPEAKERPHONE"; + field public static final java.lang.String GATEWAY_ORIGINAL_ADDRESS = "android.telecomm.extra.GATEWAY_ORIGINAL_ADDRESS"; + field public static final java.lang.String GATEWAY_PROVIDER_PACKAGE = "android.telecomm.extra.GATEWAY_PROVIDER_PACKAGE"; field public static final int PRESENTATION_ALLOWED = 1; // 0x1 field public static final int PRESENTATION_PAYPHONE = 4; // 0x4 field public static final int PRESENTATION_RESTRICTED = 2; // 0x2 @@ -33837,8 +33837,6 @@ package android.view { method public boolean hasTransientState(); method public boolean hasWindowFocus(); method public static android.view.View inflate(android.content.Context, int, android.view.ViewGroup); - method protected void initializeFadingEdge(android.content.res.TypedArray); - method protected void initializeScrollbars(android.content.res.TypedArray); method public void invalidate(android.graphics.Rect); method public void invalidate(int, int, int, int); method public void invalidate(); @@ -34885,6 +34883,7 @@ package android.view { field public static final int FEATURE_ACTION_BAR = 8; // 0x8 field public static final int FEATURE_ACTION_BAR_OVERLAY = 9; // 0x9 field public static final int FEATURE_ACTION_MODE_OVERLAY = 10; // 0xa + field public static final int FEATURE_ACTIVITY_TRANSITIONS = 13; // 0xd field public static final int FEATURE_CONTENT_TRANSITIONS = 12; // 0xc field public static final int FEATURE_CONTEXT_MENU = 6; // 0x6 field public static final int FEATURE_CUSTOM_TITLE = 7; // 0x7 @@ -39121,9 +39120,7 @@ package android.widget { method public float getShadowRadius(); method public final boolean getShowSoftInputOnFocus(); method public java.lang.CharSequence getText(); - method public static int getTextColor(android.content.Context, android.content.res.TypedArray, int); method public final android.content.res.ColorStateList getTextColors(); - method public static android.content.res.ColorStateList getTextColors(android.content.Context, android.content.res.TypedArray); method public java.util.Locale getTextLocale(); method public float getTextScaleX(); method public float getTextSize(); diff --git a/api/removed.txt b/api/removed.txt index c8a3b4b..8972679 100644 --- a/api/removed.txt +++ b/api/removed.txt @@ -24,43 +24,22 @@ package android.os { package android.view { + public class View implements android.view.accessibility.AccessibilityEventSource android.graphics.drawable.Drawable.Callback android.view.KeyEvent.Callback { + method protected void initializeFadingEdge(android.content.res.TypedArray); + method protected void initializeScrollbars(android.content.res.TypedArray); + } + public static class WindowManager.LayoutParams extends android.view.ViewGroup.LayoutParams implements android.os.Parcelable { field public static final int TYPE_KEYGUARD = 2004; // 0x7d4 } } -package android.view.inputmethod { - - public class BaseInputConnection implements android.view.inputmethod.InputConnection { - method public final boolean requestUpdateCursorAnchorInfo(int); - } - - public final class CursorAnchorInfo implements android.os.Parcelable { - method public android.graphics.RectF getCharacterRect(int); - method public int getCharacterRectFlags(int); - method public boolean isInsertionMarkerClipped(); - field public static final int CHARACTER_RECT_TYPE_FULLY_VISIBLE = 1; // 0x1 - field public static final int CHARACTER_RECT_TYPE_INVISIBLE = 3; // 0x3 - field public static final int CHARACTER_RECT_TYPE_MASK = 15; // 0xf - field public static final int CHARACTER_RECT_TYPE_NOT_FEASIBLE = 4; // 0x4 - field public static final int CHARACTER_RECT_TYPE_PARTIALLY_VISIBLE = 2; // 0x2 - field public static final int CHARACTER_RECT_TYPE_UNSPECIFIED = 0; // 0x0 - } - - public static final class CursorAnchorInfo.Builder { - method public android.view.inputmethod.CursorAnchorInfo.Builder addCharacterRect(int, float, float, float, float, int); - method public android.view.inputmethod.CursorAnchorInfo.Builder setInsertionMarkerLocation(float, float, float, float, boolean); - } - - public abstract interface InputConnection { - method public abstract boolean requestUpdateCursorAnchorInfo(int); - field public static final int REQUEST_UPDATE_CURSOR_ANCHOR_INFO_MONITOR = 2; // 0x2 - field public static final int REQUEST_UPDATE_CURSOR_UPDATE_IMMEDIATE = 1; // 0x1 - } +package android.widget { - public class InputConnectionWrapper implements android.view.inputmethod.InputConnection { - method public final boolean requestUpdateCursorAnchorInfo(int); + public class TextView extends android.view.View implements android.view.ViewTreeObserver.OnPreDrawListener { + method public static int getTextColor(android.content.Context, android.content.res.TypedArray, int); + method public static android.content.res.ColorStateList getTextColors(android.content.Context, android.content.res.TypedArray); } } diff --git a/cmds/app_process/app_main.cpp b/cmds/app_process/app_main.cpp index 6e77e13..1bb28c3 100644 --- a/cmds/app_process/app_main.cpp +++ b/cmds/app_process/app_main.cpp @@ -133,8 +133,7 @@ static size_t computeArgBlockSize(int argc, char* const argv[]) { // names if the zygote command line decreases in size. uintptr_t start = reinterpret_cast<uintptr_t>(argv[0]); uintptr_t end = reinterpret_cast<uintptr_t>(argv[argc - 1]); - end += strlen(argv[argc - 1]); - + end += strlen(argv[argc - 1]) + 1; return (end - start); } @@ -220,15 +219,27 @@ int main(int argc, char* const argv[]) // // For zygote starts, all remaining arguments are passed to the zygote. // main function. + // + // Note that we must copy argument string values since we will rewrite the + // entire argument block when we apply the nice name to argv0. - - int i = runtime.addVmArguments(argc, argv); + int i; + for (i = 0; i < argc; i++) { + if (argv[i][0] != '-') { + break; + } + if (argv[i][1] == '-' && argv[i][2] == 0) { + ++i; // Skip --. + break; + } + runtime.addOption(strdup(argv[i])); + } // Parse runtime arguments. Stop at first unrecognized option. bool zygote = false; bool startSystemServer = false; bool application = false; - const char* niceName = NULL; + String8 niceName; String8 className; ++i; // Skip unused "parent dir" argument. @@ -242,7 +253,7 @@ int main(int argc, char* const argv[]) } else if (strcmp(arg, "--application") == 0) { application = true; } else if (strncmp(arg, "--nice-name=", 12) == 0) { - niceName = arg + 12; + niceName.setTo(arg + 12); } else if (strncmp(arg, "--", 2) != 0) { className.setTo(arg); break; @@ -287,9 +298,9 @@ int main(int argc, char* const argv[]) } } - if (niceName && *niceName) { - runtime.setArgv0(niceName); - set_process_name(niceName); + if (!niceName.isEmpty()) { + runtime.setArgv0(niceName.string()); + set_process_name(niceName.string()); } if (zygote) { diff --git a/cmds/dpm/Android.mk b/cmds/dpm/Android.mk new file mode 100644 index 0000000..9f5aee4 --- /dev/null +++ b/cmds/dpm/Android.mk @@ -0,0 +1,15 @@ +# 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 := dpm +include $(BUILD_JAVA_LIBRARY) + +include $(CLEAR_VARS) +LOCAL_MODULE := dpm +LOCAL_SRC_FILES := dpm +LOCAL_MODULE_CLASS := EXECUTABLES +LOCAL_MODULE_TAGS := optional +include $(BUILD_PREBUILT) diff --git a/cmds/dpm/MODULE_LICENSE_APACHE2 b/cmds/dpm/MODULE_LICENSE_APACHE2 new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/cmds/dpm/MODULE_LICENSE_APACHE2 diff --git a/cmds/dpm/NOTICE b/cmds/dpm/NOTICE new file mode 100644 index 0000000..316b4eb --- /dev/null +++ b/cmds/dpm/NOTICE @@ -0,0 +1,190 @@ + + 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. + + 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/dpm/dpm b/cmds/dpm/dpm new file mode 100755 index 0000000..c2e5cbb --- /dev/null +++ b/cmds/dpm/dpm @@ -0,0 +1,6 @@ +# Script to start "dpm" on the device +# +base=/system +export CLASSPATH=$base/framework/dpm.jar +exec app_process $base/bin com.android.commands.dpm.Dpm "$@" + diff --git a/cmds/dpm/src/com/android/commands/dpm/Dpm.java b/cmds/dpm/src/com/android/commands/dpm/Dpm.java new file mode 100644 index 0000000..724b312 --- /dev/null +++ b/cmds/dpm/src/com/android/commands/dpm/Dpm.java @@ -0,0 +1,77 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.commands.dpm; + +import android.app.admin.IDevicePolicyManager; +import android.content.Context; +import android.os.RemoteException; +import android.os.ServiceManager; + +import com.android.internal.os.BaseCommand; + +import java.io.PrintStream; + +public final class Dpm extends BaseCommand { + + /** + * Command-line entry point. + * + * @param args The command-line arguments + */ + public static void main(String[] args) { + (new Dpm()).run(args); + } + + private static final String COMMAND_SET_DEVICE_OWNER = "set-device-owner"; + + private IDevicePolicyManager mDevicePolicyManager; + + @Override + public void onShowUsage(PrintStream out) { + out.println("usage: adb shell dpm [subcommand] [options]\n" + + "\n" + + "usage: adb shell dpm set-device-owner <PACKAGE>\n" + + " <PACKAGE> an Android package name.\n"); + } + + @Override + public void onRun() throws Exception { + mDevicePolicyManager = IDevicePolicyManager.Stub.asInterface( + ServiceManager.getService(Context.DEVICE_POLICY_SERVICE)); + if (mDevicePolicyManager == null) { + showError("Error: Could not access the Device Policy Manager. Is the system running?"); + return; + } + + String command = nextArgRequired(); + switch (command) { + case COMMAND_SET_DEVICE_OWNER: + runSetDeviceOwner(nextArgRequired()); + break; + default: + showError("Error: unknown command '" + command + "'"); + } + } + + private void runSetDeviceOwner(String packageName) throws RemoteException { + if (mDevicePolicyManager.setDeviceOwner(packageName, null)) { + System.out.println("Device owner set to package " + packageName); + } else { + showError("Error: Can't set package " + packageName + " as device owner."); + } + } +}
\ No newline at end of file diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java index 89a9692..701ab1d 100644 --- a/core/java/android/app/Activity.java +++ b/core/java/android/app/Activity.java @@ -4756,7 +4756,7 @@ public class Activity extends ContextThemeWrapper * Activity through a returning activity transition, giving you the resultCode * and any additional data from it. This method will only be called if the activity * set a result code other than {@link #RESULT_CANCELED} and it supports activity - * transitions with {@link Window#FEATURE_CONTENT_TRANSITIONS}. + * transitions with {@link Window#FEATURE_ACTIVITY_TRANSITIONS}. * * <p>The purpose of this function is to let the called Activity send a hint about * its state so that this underlying Activity can prepare to be exposed. A call to @@ -5781,7 +5781,7 @@ public class Activity extends ContextThemeWrapper * When {@link android.app.ActivityOptions#makeSceneTransitionAnimation(Activity, * android.view.View, String)} was used to start an Activity, <var>callback</var> * will be called to handle shared elements on the <i>launched</i> Activity. This requires - * {@link Window#FEATURE_CONTENT_TRANSITIONS}. + * {@link Window#FEATURE_ACTIVITY_TRANSITIONS}. * * @param callback Used to manipulate shared element transitions on the launched Activity. */ @@ -5797,7 +5797,7 @@ public class Activity extends ContextThemeWrapper * android.view.View, String)} was used to start an Activity, <var>callback</var> * will be called to handle shared elements on the <i>launching</i> Activity. Most * calls will only come when returning from the started Activity. - * This requires {@link Window#FEATURE_CONTENT_TRANSITIONS}. + * This requires {@link Window#FEATURE_ACTIVITY_TRANSITIONS}. * * @param callback Used to manipulate shared element transitions on the launching Activity. */ diff --git a/core/java/android/app/ActivityOptions.java b/core/java/android/app/ActivityOptions.java index 213c7f6..cd6a4f5 100644 --- a/core/java/android/app/ActivityOptions.java +++ b/core/java/android/app/ActivityOptions.java @@ -414,7 +414,7 @@ public class ActivityOptions { * exit Transition. The position of the shared element in the launched Activity will be the * epicenter of its entering Transition. * - * <p>This requires {@link android.view.Window#FEATURE_CONTENT_TRANSITIONS} to be + * <p>This requires {@link android.view.Window#FEATURE_ACTIVITY_TRANSITIONS} to be * enabled on the calling Activity to cause an exit transition. The same must be in * the called Activity to get an entering transition.</p> * @param activity The Activity whose window contains the shared elements. @@ -438,7 +438,7 @@ public class ActivityOptions { * will be used as the epicenter for the exit Transition. The position of the associated * shared element in the launched Activity will be the epicenter of its entering Transition. * - * <p>This requires {@link android.view.Window#FEATURE_CONTENT_TRANSITIONS} to be + * <p>This requires {@link android.view.Window#FEATURE_ACTIVITY_TRANSITIONS} to be * enabled on the calling Activity to cause an exit transition. The same must be in * the called Activity to get an entering transition.</p> * @param activity The Activity whose window contains the shared elements. @@ -453,7 +453,7 @@ public class ActivityOptions { public static ActivityOptions makeSceneTransitionAnimation(Activity activity, Pair<View, String>... sharedElements) { ActivityOptions opts = new ActivityOptions(); - if (!activity.getWindow().hasFeature(Window.FEATURE_CONTENT_TRANSITIONS)) { + if (!activity.getWindow().hasFeature(Window.FEATURE_ACTIVITY_TRANSITIONS)) { opts.mAnimationType = ANIM_DEFAULT; return opts; } diff --git a/core/java/android/app/ActivityTransitionState.java b/core/java/android/app/ActivityTransitionState.java index ad4a22b..bc2e6ca 100644 --- a/core/java/android/app/ActivityTransitionState.java +++ b/core/java/android/app/ActivityTransitionState.java @@ -144,7 +144,7 @@ class ActivityTransitionState { } public void setEnterActivityOptions(Activity activity, ActivityOptions options) { - if (activity.getWindow().hasFeature(Window.FEATURE_CONTENT_TRANSITIONS) + if (activity.getWindow().hasFeature(Window.FEATURE_ACTIVITY_TRANSITIONS) && options != null && mEnterActivityOptions == null && mEnterTransitionCoordinator == null && options.getAnimationType() == ActivityOptions.ANIM_SCENE_TRANSITION) { @@ -272,7 +272,7 @@ class ActivityTransitionState { } public void startExitOutTransition(Activity activity, Bundle options) { - if (!activity.getWindow().hasFeature(Window.FEATURE_CONTENT_TRANSITIONS)) { + if (!activity.getWindow().hasFeature(Window.FEATURE_ACTIVITY_TRANSITIONS)) { return; } ActivityOptions activityOptions = new ActivityOptions(options); diff --git a/core/java/android/app/ApplicationPackageManager.java b/core/java/android/app/ApplicationPackageManager.java index d746745..6860683 100644 --- a/core/java/android/app/ApplicationPackageManager.java +++ b/core/java/android/app/ApplicationPackageManager.java @@ -66,6 +66,7 @@ import android.view.Display; import com.android.internal.annotations.GuardedBy; import com.android.internal.util.Preconditions; +import com.android.internal.util.UserIcons; import dalvik.system.VMRuntime; @@ -1660,7 +1661,11 @@ final class ApplicationPackageManager extends PackageManager { */ public Drawable loadItemIcon(PackageItemInfo itemInfo, ApplicationInfo appInfo) { if (itemInfo.showUserIcon != UserHandle.USER_NULL) { - return new BitmapDrawable(getUserManager().getUserIcon(itemInfo.showUserIcon)); + Bitmap bitmap = getUserManager().getUserIcon(itemInfo.showUserIcon); + if (bitmap == null) { + return UserIcons.getDefaultUserIcon(itemInfo.showUserIcon, /* light= */ false); + } + return new BitmapDrawable(bitmap); } Drawable dr = null; if (itemInfo.packageName != null) { diff --git a/core/java/android/app/EnterTransitionCoordinator.java b/core/java/android/app/EnterTransitionCoordinator.java index 922561d..9ca150d 100644 --- a/core/java/android/app/EnterTransitionCoordinator.java +++ b/core/java/android/app/EnterTransitionCoordinator.java @@ -329,7 +329,10 @@ class EnterTransitionCoordinator extends ActivityTransitionCoordinator { @Override public void run() { if (mAnimations++ < MIN_ANIMATION_FRAMES) { - getDecor().postOnAnimation(this); + View decorView = getDecor(); + if (decorView != null) { + decorView.postOnAnimation(this); + } } else if (mResultReceiver != null) { mResultReceiver.send(MSG_HIDE_SHARED_ELEMENTS, null); mResultReceiver = null; // all done sending messages. diff --git a/core/java/android/app/INotificationManager.aidl b/core/java/android/app/INotificationManager.aidl index 7d4512b..bdcff38 100644 --- a/core/java/android/app/INotificationManager.aidl +++ b/core/java/android/app/INotificationManager.aidl @@ -71,7 +71,6 @@ interface INotificationManager ComponentName getEffectsSuppressor(); boolean matchesCallFilter(in Bundle extras); - boolean matchesCallFilterAsUser(in Bundle extras, int userId); ZenModeConfig getZenModeConfig(); boolean setZenModeConfig(in ZenModeConfig config); diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java index f9e4895..31b39eb 100644 --- a/core/java/android/app/Notification.java +++ b/core/java/android/app/Notification.java @@ -2680,6 +2680,8 @@ public class Notification implements Parcelable contentView.setViewVisibility(R.id.line3, View.GONE); contentView.setViewVisibility(R.id.overflow_divider, View.GONE); contentView.setViewVisibility(R.id.progress, View.GONE); + contentView.setViewVisibility(R.id.chronometer, View.GONE); + contentView.setViewVisibility(R.id.time, View.GONE); } private RemoteViews applyStandardTemplate(int resId) { @@ -2775,8 +2777,6 @@ public class Notification implements Parcelable contentView.setViewVisibility(R.id.time, View.VISIBLE); contentView.setLong(R.id.time, "setTime", mWhen); } - } else { - contentView.setViewVisibility(R.id.time, View.GONE); } // Adjust padding depending on line count and font size. diff --git a/core/java/android/app/admin/DeviceAdminReceiver.java b/core/java/android/app/admin/DeviceAdminReceiver.java index e2f175c..836f682 100644 --- a/core/java/android/app/admin/DeviceAdminReceiver.java +++ b/core/java/android/app/admin/DeviceAdminReceiver.java @@ -221,6 +221,12 @@ public class DeviceAdminReceiver extends BroadcastReceiver { */ @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) public static final String ACTION_PROFILE_PROVISIONING_COMPLETE = + "android.app.action.PROFILE_PROVISIONING_COMPLETE"; + + /** + * Do not use, replaced by {@link #ACTION_PROFILE_PROVISIONING_COMPLETE} + */ + private static final String LEGACY_ACTION_PROFILE_PROVISIONING_COMPLETE = "android.app.action.ACTION_PROFILE_PROVISIONING_COMPLETE"; /** @@ -431,6 +437,9 @@ public class DeviceAdminReceiver extends BroadcastReceiver { onPasswordExpiring(context, intent); } else if (ACTION_PROFILE_PROVISIONING_COMPLETE.equals(action)) { onProfileProvisioningComplete(context, intent); + // TODO: remove when nobody depends on this + } else if (LEGACY_ACTION_PROFILE_PROVISIONING_COMPLETE.equals(action)) { + onProfileProvisioningComplete(context, intent); } else if (ACTION_LOCK_TASK_ENTERING.equals(action)) { String pkg = intent.getStringExtra(EXTRA_LOCK_TASK_PACKAGE); onLockTaskModeEntering(context, intent, pkg); diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java index 4a21913..13ed8d1 100644 --- a/core/java/android/app/admin/DevicePolicyManager.java +++ b/core/java/android/app/admin/DevicePolicyManager.java @@ -148,14 +148,16 @@ public class DevicePolicyManager { * created for. Used with {@link #ACTION_PROVISION_MANAGED_PROFILE} and * {@link DeviceAdminReceiver#ACTION_PROFILE_PROVISIONING_COMPLETE}. * + * <p> This extra is part of the {@link #EXTRA_PROVISIONING_ADMIN_EXTRAS_BUNDLE}. + * * <p> If the {@link #ACTION_PROVISION_MANAGED_PROFILE} intent that starts managed provisioning * contains this extra, it is forwarded in the * {@link DeviceAdminReceiver#ACTION_PROFILE_PROVISIONING_COMPLETE} intent to the mobile * device management application that was set as the profile owner during provisioning. * It is usually used to avoid that the user has to enter their email address twice. */ - public static final String KEY_PROVISIONING_EMAIL_ADDRESS - = "android.app.key.PROVISIONING_EMAIL_ADDRESS"; + public static final String EXTRA_PROVISIONING_EMAIL_ADDRESS + = "android.app.extra.PROVISIONING_EMAIL_ADDRESS"; /** * A String extra holding the time zone {@link android.app.AlarmManager} that the device diff --git a/core/java/android/bluetooth/BluetoothGatt.java b/core/java/android/bluetooth/BluetoothGatt.java index d77a77b..2276229 100644 --- a/core/java/android/bluetooth/BluetoothGatt.java +++ b/core/java/android/bluetooth/BluetoothGatt.java @@ -51,6 +51,7 @@ public final class BluetoothGatt implements BluetoothProfile { private int mConnState; private final Object mStateLock = new Object(); private Boolean mDeviceBusy = false; + private Boolean mIsCongested = false; private int mTransport; private static final int CONN_STATE_IDLE = 0; @@ -616,7 +617,7 @@ public final class BluetoothGatt implements BluetoothProfile { + " congested=" + congested); if (!address.equals(mDevice.getAddress())) return; try { - mCallback.onConnectionCongested(BluetoothGatt.this, congested); + mIsCongested = congested; } catch (Exception ex) { Log.w(TAG, "Unhandled exception in callback", ex); } diff --git a/core/java/android/bluetooth/BluetoothGattCallback.java b/core/java/android/bluetooth/BluetoothGattCallback.java index 19900ec..a915620 100644 --- a/core/java/android/bluetooth/BluetoothGattCallback.java +++ b/core/java/android/bluetooth/BluetoothGattCallback.java @@ -152,18 +152,4 @@ public abstract class BluetoothGattCallback { */ public void onMtuChanged(BluetoothGatt gatt, int mtu, int status) { } - - /** - * Callback indicating that a remote device connection congestestion status has changed. - * - * An application should refrain from sending additional data to a remote device when - * a callback is received with the congested flag set to true. Once the congestion status - * is cleared up, the application will receive an additional callback with the congested - * flag set to false. - * - * @param gatt The GATT client associated with the remote device - * @param congested true, if the connection is currently congested - */ - public void onConnectionCongested(BluetoothGatt gatt, boolean congested) { - } } diff --git a/core/java/android/bluetooth/BluetoothGattServer.java b/core/java/android/bluetooth/BluetoothGattServer.java index c8df60e..a7f117b 100644 --- a/core/java/android/bluetooth/BluetoothGattServer.java +++ b/core/java/android/bluetooth/BluetoothGattServer.java @@ -48,6 +48,7 @@ public final class BluetoothGattServer implements BluetoothProfile { private BluetoothAdapter mAdapter; private IBluetoothGatt mService; private BluetoothGattServerCallback mCallback; + private Boolean mIsCongested = false; private Object mServerIfLock = new Object(); private int mServerIf; @@ -297,7 +298,7 @@ public final class BluetoothGattServer implements BluetoothProfile { if (device == null) return; try { - mCallback.onConnectionCongested(device, congested); + mIsCongested = congested; } catch (Exception ex) { Log.w(TAG, "Unhandled exception in callback", ex); } diff --git a/core/java/android/bluetooth/BluetoothGattServerCallback.java b/core/java/android/bluetooth/BluetoothGattServerCallback.java index b0ddc26..1dd06f2 100644 --- a/core/java/android/bluetooth/BluetoothGattServerCallback.java +++ b/core/java/android/bluetooth/BluetoothGattServerCallback.java @@ -145,18 +145,4 @@ public abstract class BluetoothGattServerCallback { */ public void onNotificationSent(BluetoothDevice device, int status) { } - - /** - * Callback indicating that a remote device connection congestestion status has changed. - * - * An application should refrain from sending additional data (notifications, indications - * etc.) to a remote device when a callback is received with the congested flag set - * to true. Once the congestion status is cleared up, the application will receive an - * additional callback with the congested flag set to false. - * - * @param device The remote device that triggered the congestion state change - * @param congested true, if the connection is currently congested - */ - public void onConnectionCongested(BluetoothDevice device, boolean congested) { - } } diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java index 61dd747..4f20705 100644 --- a/core/java/android/content/Context.java +++ b/core/java/android/content/Context.java @@ -2037,6 +2037,7 @@ public abstract class Context { * argument for use by system server and other multi-user aware code. * @hide */ + @SystemApi public boolean bindServiceAsUser(Intent service, ServiceConnection conn, int flags, UserHandle user) { throw new RuntimeException("Not implemented. Must override in a subclass."); } diff --git a/core/java/android/content/pm/ActivityInfo.java b/core/java/android/content/pm/ActivityInfo.java index 8d3126d..641f843 100644 --- a/core/java/android/content/pm/ActivityInfo.java +++ b/core/java/android/content/pm/ActivityInfo.java @@ -657,6 +657,7 @@ public class ActivityInfo extends ComponentInfo softInputMode = orig.softInputMode; uiOptions = orig.uiOptions; parentActivityName = orig.parentActivityName; + maxRecents = orig.maxRecents; } /** @@ -728,6 +729,7 @@ public class ActivityInfo extends ComponentInfo dest.writeInt(uiOptions); dest.writeString(parentActivityName); dest.writeInt(persistableMode); + dest.writeInt(maxRecents); } public static final Parcelable.Creator<ActivityInfo> CREATOR @@ -754,5 +756,6 @@ public class ActivityInfo extends ComponentInfo uiOptions = source.readInt(); parentActivityName = source.readString(); persistableMode = source.readInt(); + maxRecents = source.readInt(); } } diff --git a/core/java/android/content/pm/LauncherApps.java b/core/java/android/content/pm/LauncherApps.java index d49bc50..5ee0b67 100644 --- a/core/java/android/content/pm/LauncherApps.java +++ b/core/java/android/content/pm/LauncherApps.java @@ -500,11 +500,18 @@ public class LauncherApps { } } - /** STOPSHIP remove when launcher 3 has been updated */ + /** + * TODO Remove after 2014-09-22 + * @hide + */ public void addCallback(Callback callback) { registerCallback(callback); } - /** STOPSHIP remove when launcher 3 has been updated */ + + /** + * TODO Remove after 2014-09-22 + * @hide + */ public void removeCallback(Callback callback) { unregisterCallback(callback); } diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java index ddb0a6d..ffde7ce 100644 --- a/core/java/android/content/pm/PackageParser.java +++ b/core/java/android/content/pm/PackageParser.java @@ -3308,7 +3308,8 @@ public class PackageParser { info.softInputMode = target.info.softInputMode; info.uiOptions = target.info.uiOptions; info.parentActivityName = target.info.parentActivityName; - + info.maxRecents = target.info.maxRecents; + Activity a = new Activity(mParseActivityAliasArgs, info); if (outError[0] != null) { sa.recycle(); diff --git a/core/java/android/hardware/camera2/legacy/LegacyMetadataMapper.java b/core/java/android/hardware/camera2/legacy/LegacyMetadataMapper.java index 3c0e0e4..c36b63a 100644 --- a/core/java/android/hardware/camera2/legacy/LegacyMetadataMapper.java +++ b/core/java/android/hardware/camera2/legacy/LegacyMetadataMapper.java @@ -165,6 +165,12 @@ public class LegacyMetadataMapper { private static void mapCharacteristicsFromParameters(CameraMetadataNative m, Camera.Parameters p) { + + /* + * colorCorrection.* + */ + m.set(COLOR_CORRECTION_AVAILABLE_ABERRATION_MODES, + new int[] { COLOR_CORRECTION_ABERRATION_MODE_FAST }); /* * control.ae* */ @@ -196,6 +202,12 @@ public class LegacyMetadataMapper { mapJpeg(m, p); /* + * noiseReduction.* + */ + m.set(NOISE_REDUCTION_AVAILABLE_NOISE_REDUCTION_MODES, + new int[] { NOISE_REDUCTION_MODE_FAST }); + + /* * scaler.* */ mapScaler(m, p); @@ -626,6 +638,7 @@ public class LegacyMetadataMapper { // Note: We only list public keys. Native HALs should list ALL keys regardless of visibility. Key<?> availableKeys[] = new Key<?>[] { + CameraCharacteristics.COLOR_CORRECTION_AVAILABLE_ABERRATION_MODES , CameraCharacteristics.CONTROL_AE_AVAILABLE_ANTIBANDING_MODES , CameraCharacteristics.CONTROL_AE_AVAILABLE_MODES , CameraCharacteristics.CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES , @@ -642,6 +655,7 @@ public class LegacyMetadataMapper { CameraCharacteristics.JPEG_AVAILABLE_THUMBNAIL_SIZES , CameraCharacteristics.LENS_FACING , CameraCharacteristics.LENS_INFO_AVAILABLE_FOCAL_LENGTHS , + CameraCharacteristics.NOISE_REDUCTION_AVAILABLE_NOISE_REDUCTION_MODES , CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES , CameraCharacteristics.REQUEST_MAX_NUM_OUTPUT_STREAMS , CameraCharacteristics.REQUEST_PARTIAL_RESULT_COUNT , @@ -653,6 +667,7 @@ public class LegacyMetadataMapper { CameraCharacteristics.SENSOR_INFO_ACTIVE_ARRAY_SIZE , CameraCharacteristics.SENSOR_INFO_PHYSICAL_SIZE , CameraCharacteristics.SENSOR_INFO_PIXEL_ARRAY_SIZE , + CameraCharacteristics.SENSOR_INFO_TIMESTAMP_SOURCE , CameraCharacteristics.SENSOR_ORIENTATION , CameraCharacteristics.STATISTICS_INFO_AVAILABLE_FACE_DETECT_MODES , CameraCharacteristics.STATISTICS_INFO_MAX_FACE_COUNT , @@ -676,6 +691,7 @@ public class LegacyMetadataMapper { */ { CaptureRequest.Key<?> defaultAvailableKeys[] = new CaptureRequest.Key<?>[] { + CaptureRequest.COLOR_CORRECTION_ABERRATION_MODE, CaptureRequest.CONTROL_AE_ANTIBANDING_MODE, CaptureRequest.CONTROL_AE_EXPOSURE_COMPENSATION, CaptureRequest.CONTROL_AE_LOCK, @@ -699,6 +715,7 @@ public class LegacyMetadataMapper { CaptureRequest.JPEG_THUMBNAIL_QUALITY, CaptureRequest.JPEG_THUMBNAIL_SIZE, CaptureRequest.LENS_FOCAL_LENGTH, + CaptureRequest.NOISE_REDUCTION_MODE, CaptureRequest.SCALER_CROP_REGION, CaptureRequest.STATISTICS_FACE_DETECT_MODE, }; @@ -723,6 +740,7 @@ public class LegacyMetadataMapper { */ { CaptureResult.Key<?> defaultAvailableKeys[] = new CaptureResult.Key<?>[] { + CaptureResult.COLOR_CORRECTION_ABERRATION_MODE , CaptureResult.CONTROL_AE_ANTIBANDING_MODE , CaptureResult.CONTROL_AE_EXPOSURE_COMPENSATION , CaptureResult.CONTROL_AE_LOCK , @@ -740,6 +758,7 @@ public class LegacyMetadataMapper { CaptureResult.JPEG_QUALITY , CaptureResult.JPEG_THUMBNAIL_QUALITY , CaptureResult.LENS_FOCAL_LENGTH , + CaptureResult.NOISE_REDUCTION_MODE , CaptureResult.REQUEST_PIPELINE_DEPTH , CaptureResult.SCALER_CROP_REGION , CaptureResult.SENSOR_TIMESTAMP , @@ -844,6 +863,13 @@ public class LegacyMetadataMapper { m.set(SENSOR_INFO_PHYSICAL_SIZE, new SizeF(width, height)); // in mm } + + /* + * sensor.info.timestampSource + */ + { + m.set(SENSOR_INFO_TIMESTAMP_SOURCE, SENSOR_INFO_TIMESTAMP_SOURCE_UNKNOWN); + } } private static void mapStatistics(CameraMetadataNative m, Parameters p) { diff --git a/core/java/android/hardware/camera2/legacy/LegacyRequestMapper.java b/core/java/android/hardware/camera2/legacy/LegacyRequestMapper.java index 42ee4fa..42fe897 100644 --- a/core/java/android/hardware/camera2/legacy/LegacyRequestMapper.java +++ b/core/java/android/hardware/camera2/legacy/LegacyRequestMapper.java @@ -80,6 +80,20 @@ public class LegacyRequestMapper { } } + /* + * colorCorrection.* + */ + // colorCorrection.aberrationMode + { + int aberrationMode = ParamsUtils.getOrDefault(request, + COLOR_CORRECTION_ABERRATION_MODE, + /*defaultValue*/COLOR_CORRECTION_ABERRATION_MODE_FAST); + + if (aberrationMode != COLOR_CORRECTION_ABERRATION_MODE_FAST) { + Log.w(TAG, "convertRequestToMetadata - Ignoring unsupported " + + "colorCorrection.aberrationMode = " + aberrationMode); + } + } /* * control.ae* @@ -419,6 +433,21 @@ public class LegacyRequestMapper { } } } + + /* + * noiseReduction.* + */ + // noiseReduction.mode + { + int mode = ParamsUtils.getOrDefault(request, + NOISE_REDUCTION_MODE, + /*defaultValue*/NOISE_REDUCTION_MODE_FAST); + + if (mode != NOISE_REDUCTION_MODE_FAST) { + Log.w(TAG, "convertRequestToMetadata - Ignoring unsupported " + + "noiseReduction.mode = " + mode); + } + } } private static boolean checkForCompleteGpsData(Location location) { diff --git a/core/java/android/hardware/camera2/legacy/LegacyResultMapper.java b/core/java/android/hardware/camera2/legacy/LegacyResultMapper.java index ddaa6ee..bad1d28 100644 --- a/core/java/android/hardware/camera2/legacy/LegacyResultMapper.java +++ b/core/java/android/hardware/camera2/legacy/LegacyResultMapper.java @@ -28,14 +28,12 @@ import android.hardware.camera2.legacy.ParameterUtils.ZoomData; import android.hardware.camera2.params.MeteringRectangle; import android.hardware.camera2.utils.ListUtils; import android.hardware.camera2.utils.ParamsUtils; -import android.location.Location; import android.util.Log; import android.util.Size; import java.util.ArrayList; import java.util.List; -import static com.android.internal.util.Preconditions.*; import static android.hardware.camera2.CaptureResult.*; /** @@ -73,7 +71,7 @@ public class LegacyResultMapper { result = new CameraMetadataNative(mCachedResult); cached = true; } else { - result = convertResultMetadata(legacyRequest, timestamp); + result = convertResultMetadata(legacyRequest); cached = false; // Always cache a *copy* of the metadata result, @@ -106,12 +104,9 @@ public class LegacyResultMapper { * Generate capture result metadata from the legacy camera request. * * @param legacyRequest a non-{@code null} legacy request containing the latest parameters - * @param timestamp the timestamp to use for this result in nanoseconds. - * * @return a {@link CameraMetadataNative} object containing result metadata. */ - private static CameraMetadataNative convertResultMetadata(LegacyRequest legacyRequest, - long timestamp) { + private static CameraMetadataNative convertResultMetadata(LegacyRequest legacyRequest) { CameraCharacteristics characteristics = legacyRequest.characteristics; CaptureRequest request = legacyRequest.captureRequest; Size previewSize = legacyRequest.previewSize; @@ -125,6 +120,15 @@ public class LegacyResultMapper { request.get(CaptureRequest.SCALER_CROP_REGION), previewSize, params); /* + * colorCorrection + */ + // colorCorrection.aberrationMode + { + // Always hardcoded to FAST + result.set(COLOR_CORRECTION_ABERRATION_MODE, COLOR_CORRECTION_ABERRATION_MODE_FAST); + } + + /* * control */ @@ -274,7 +278,12 @@ public class LegacyResultMapper { Log.w(TAG, "Null thumbnail size received from parameters."); } - // TODO: Remaining result metadata tags conversions. + /* + * noiseReduction.* + */ + // noiseReduction.mode + result.set(NOISE_REDUCTION_MODE, NOISE_REDUCTION_MODE_FAST); + return result; } diff --git a/core/java/android/hardware/hdmi/HdmiTvClient.java b/core/java/android/hardware/hdmi/HdmiTvClient.java index c37fb5b..9d92fd9 100644 --- a/core/java/android/hardware/hdmi/HdmiTvClient.java +++ b/core/java/android/hardware/hdmi/HdmiTvClient.java @@ -36,9 +36,9 @@ public final class HdmiTvClient extends HdmiClient { private static final String TAG = "HdmiTvClient"; /** - * Size of MHL scratchpad register. + * Size of MHL register for vendor command */ - public static final int SCRATCHPAD_DATA_SIZE = 16; + public static final int VENDOR_DATA_SIZE = 16; HdmiTvClient(IHdmiControlService service) { super(service); @@ -332,31 +332,31 @@ public final class HdmiTvClient extends HdmiClient { } /** - * Interface used to get incoming MHL scratchpad command. + * Interface used to get incoming MHL vendor command. */ - public interface HdmiMhlScratchpadCommandListener { + public interface HdmiMhlVendorCommandListener { void onReceived(int portId, int offset, int length, byte[] data); } /** - * Set {@link HdmiMhlScratchpadCommandListener} to get incoming MHL sSratchpad command. + * Set {@link HdmiMhlVendorCommandListener} to get incoming MHL vendor command. * - * @param listener to receive incoming MHL Scratchpad command + * @param listener to receive incoming MHL vendor command */ - public void setHdmiMhlScratchpadCommandListener(HdmiMhlScratchpadCommandListener listener) { + public void setHdmiMhlVendorCommandListener(HdmiMhlVendorCommandListener listener) { if (listener == null) { throw new IllegalArgumentException("listener must not be null."); } try { - mService.addHdmiMhlScratchpadCommandListener(getListenerWrapper(listener)); + mService.addHdmiMhlVendorCommandListener(getListenerWrapper(listener)); } catch (RemoteException e) { - Log.e(TAG, "failed to set hdmi mhl scratchpad command listener: ", e); + Log.e(TAG, "failed to set hdmi mhl vendor command listener: ", e); } } - private IHdmiMhlScratchpadCommandListener getListenerWrapper( - final HdmiMhlScratchpadCommandListener listener) { - return new IHdmiMhlScratchpadCommandListener.Stub() { + private IHdmiMhlVendorCommandListener getListenerWrapper( + final HdmiMhlVendorCommandListener listener) { + return new IHdmiMhlVendorCommandListener.Stub() { @Override public void onReceived(int portId, int offset, int length, byte[] data) { listener.onReceived(portId, offset, length, data); @@ -365,29 +365,29 @@ public final class HdmiTvClient extends HdmiClient { } /** - * Send MHL Scratchpad command to the device connected to a port of the given portId. + * Send MHL vendor command to the device connected to a port of the given portId. * - * @param portId id of port to send MHL Scratchpad command + * @param portId id of port to send MHL vendor command * @param offset offset in the in given data * @param length length of data. offset + length should be bound to length of data. - * @param data container for Scratchpad data. It should be 16 bytes. + * @param data container for vendor command data. It should be 16 bytes. * @throws IllegalArgumentException if the given parameters are invalid */ - public void sendScratchpadCommand(int portId, int offset, int length, byte[] data) { - if (data == null || data.length != SCRATCHPAD_DATA_SIZE) { - throw new IllegalArgumentException("Invalid scratchpad data."); + public void sendMhlVendorCommand(int portId, int offset, int length, byte[] data) { + if (data == null || data.length != VENDOR_DATA_SIZE) { + throw new IllegalArgumentException("Invalid vendor command data."); } - if (offset < 0 || offset >= SCRATCHPAD_DATA_SIZE) { + if (offset < 0 || offset >= VENDOR_DATA_SIZE) { throw new IllegalArgumentException("Invalid offset:" + offset); } - if (length < 0 || offset + length > SCRATCHPAD_DATA_SIZE) { + if (length < 0 || offset + length > VENDOR_DATA_SIZE) { throw new IllegalArgumentException("Invalid length:" + length); } try { - mService.sendScratchpadCommand(portId, offset, length, data); + mService.sendMhlVendorCommand(portId, offset, length, data); } catch (RemoteException e) { - Log.e(TAG, "failed to send scratchpad command: ", e); + Log.e(TAG, "failed to send vendor command: ", e); } } } diff --git a/core/java/android/hardware/hdmi/IHdmiControlService.aidl b/core/java/android/hardware/hdmi/IHdmiControlService.aidl index 3bd45ed..4866a9a 100644 --- a/core/java/android/hardware/hdmi/IHdmiControlService.aidl +++ b/core/java/android/hardware/hdmi/IHdmiControlService.aidl @@ -22,7 +22,7 @@ import android.hardware.hdmi.IHdmiControlCallback; import android.hardware.hdmi.IHdmiDeviceEventListener; import android.hardware.hdmi.IHdmiHotplugEventListener; import android.hardware.hdmi.IHdmiInputChangeListener; -import android.hardware.hdmi.IHdmiMhlScratchpadCommandListener; +import android.hardware.hdmi.IHdmiMhlVendorCommandListener; import android.hardware.hdmi.IHdmiRecordListener; import android.hardware.hdmi.IHdmiSystemAudioModeChangeListener; import android.hardware.hdmi.IHdmiVendorCommandListener; @@ -62,11 +62,12 @@ interface IHdmiControlService { void sendVendorCommand(int deviceType, int targetAddress, in byte[] params, boolean hasVendorId); void addVendorCommandListener(IHdmiVendorCommandListener listener, int deviceType); + void sendStandby(int deviceType, int deviceId); void setHdmiRecordListener(IHdmiRecordListener callback); void startOneTouchRecord(int recorderAddress, in byte[] recordSource); void stopOneTouchRecord(int recorderAddress); void startTimerRecording(int recorderAddress, int sourceType, in byte[] recordSource); void clearTimerRecording(int recorderAddress, int sourceType, in byte[] recordSource); - void sendScratchpadCommand(int portId, int offset, int length, in byte[] data); - void addHdmiMhlScratchpadCommandListener(IHdmiMhlScratchpadCommandListener listener); + void sendMhlVendorCommand(int portId, int offset, int length, in byte[] data); + void addHdmiMhlVendorCommandListener(IHdmiMhlVendorCommandListener listener); } diff --git a/core/java/android/hardware/hdmi/IHdmiMhlScratchpadCommandListener.aidl b/core/java/android/hardware/hdmi/IHdmiMhlVendorCommandListener.aidl index 4176597..4696677 100644 --- a/core/java/android/hardware/hdmi/IHdmiMhlScratchpadCommandListener.aidl +++ b/core/java/android/hardware/hdmi/IHdmiMhlVendorCommandListener.aidl @@ -17,11 +17,10 @@ package android.hardware.hdmi; /** - * Callback interface definition for MHL client to get the scratchpad - * command. + * Callback interface definition for MHL client to get the vendor command. * * @hide */ - oneway interface IHdmiMhlScratchpadCommandListener { + oneway interface IHdmiMhlVendorCommandListener { void onReceived(int portId, int offset, int length, in byte[] data); } diff --git a/core/java/android/net/VpnService.java b/core/java/android/net/VpnService.java index 050be40..c848993 100644 --- a/core/java/android/net/VpnService.java +++ b/core/java/android/net/VpnService.java @@ -62,7 +62,8 @@ import java.util.List; * conflict with each other. The system takes several actions to address * these issues. Here are some key points: * <ul> - * <li>User action is required to create a VPN connection.</li> + * <li>User action is required the first time an application creates a VPN + * connection.</li> * <li>There can be only one VPN connection running at the same time. The * existing interface is deactivated when a new one is created.</li> * <li>A system-managed notification is shown during the lifetime of a @@ -82,8 +83,8 @@ import java.util.List; * other methods in this class, and the right can be revoked at any time. * Here are the general steps to create a VPN connection: * <ol> - * <li>When the user press the button to connect, call {@link #prepare} - * and launch the returned intent.</li> + * <li>When the user presses the button to connect, call {@link #prepare} + * and launch the returned intent, if non-null.</li> * <li>When the application becomes prepared, start the service.</li> * <li>Create a tunnel to the remote server and negotiate the network * parameters for the VPN connection.</li> @@ -130,7 +131,8 @@ public class VpnService extends Service { /** * Prepare to establish a VPN connection. This method returns {@code null} - * if the VPN application is already prepared. Otherwise, it returns an + * if the VPN application is already prepared or if the user has previously + * consented to the VPN application. Otherwise, it returns an * {@link Intent} to a system activity. The application should launch the * activity using {@link Activity#startActivityForResult} to get itself * prepared. The activity may pop up a dialog to require user action, and @@ -144,6 +146,10 @@ public class VpnService extends Service { * it becomes prepared again, subsequent calls to other methods in this * class will fail. * + * <p>The user may disable the VPN at any time while it is activated, in + * which case this method will return an intent the next time it is + * executed to obtain the user's consent again. + * * @see #onRevoke */ public static Intent prepare(Context context) { @@ -212,6 +218,8 @@ public class VpnService extends Service { * * @return {@code true} on success. * @see Builder#addAddress + * + * @hide */ public boolean addAddress(InetAddress address, int prefixLength) { check(address, prefixLength); @@ -240,6 +248,8 @@ public class VpnService extends Service { * @param prefixLength The prefix length of the address. * * @return {@code true} on success. + * + * @hide */ public boolean removeAddress(InetAddress address, int prefixLength) { check(address, prefixLength); diff --git a/core/java/android/os/PowerManager.java b/core/java/android/os/PowerManager.java index 00e2e22..18b2082 100644 --- a/core/java/android/os/PowerManager.java +++ b/core/java/android/os/PowerManager.java @@ -248,7 +248,7 @@ public final class PowerManager { * {@link #PROXIMITY_SCREEN_OFF_WAKE_LOCK} wake lock until the proximity sensor * indicates that an object is not in close proximity. */ - public static final int WAIT_FOR_DISTANT_PROXIMITY = 1; + public static final int RELEASE_FLAG_WAIT_FOR_NO_PROXIMITY = 1; /** * Brightness value for fully on. @@ -961,8 +961,8 @@ public final class PowerManager { * </p> * * @param flags Combination of flag values to modify the release behavior. - * Currently only {@link #WAIT_FOR_DISTANT_PROXIMITY} is supported. Passing 0 is - * equivalent to calling {@link #release()}. + * Currently only {@link #RELEASE_FLAG_WAIT_FOR_NO_PROXIMITY} is supported. + * Passing 0 is equivalent to calling {@link #release()}. */ public void release(int flags) { synchronized (mToken) { diff --git a/core/java/android/os/UserManager.java b/core/java/android/os/UserManager.java index c76ff11..c25278f 100644 --- a/core/java/android/os/UserManager.java +++ b/core/java/android/os/UserManager.java @@ -998,6 +998,7 @@ public class UserManager { * Returns a file descriptor for the user's photo. PNG data can be read from this file. * @param userHandle the user whose photo we want to read. * @return a {@link Bitmap} of the user's photo, or null if there's no photo. + * @see com.android.internal.util.UserIcons#getDefaultUserIcon for a default. * @hide */ public Bitmap getUserIcon(int userHandle) { diff --git a/core/java/android/transition/TransitionSet.java b/core/java/android/transition/TransitionSet.java index 56db674..669621eb3 100644 --- a/core/java/android/transition/TransitionSet.java +++ b/core/java/android/transition/TransitionSet.java @@ -390,7 +390,20 @@ public class TransitionSet extends Transition { ArrayList<TransitionValues> endValuesList) { startValues = removeExcludes(startValues); endValues = removeExcludes(endValues); - for (Transition childTransition : mTransitions) { + long startDelay = getStartDelay(); + int numTransitions = mTransitions.size(); + for (int i = 0; i < numTransitions; i++) { + Transition childTransition = mTransitions.get(i); + // We only set the start delay on the first transition if we are playing + // the transitions sequentially. + if (startDelay > 0 && (mPlayTogether || i == 0)) { + long childStartDelay = childTransition.getStartDelay(); + if (childStartDelay > 0) { + childTransition.setStartDelay(startDelay + childStartDelay); + } else { + childTransition.setStartDelay(startDelay); + } + } childTransition.createAnimators(sceneRoot, startValues, endValues, startValuesList, endValuesList); } @@ -419,11 +432,17 @@ public class TransitionSet extends Transition { */ @Override protected void runAnimators() { + if (mTransitions.isEmpty()) { + start(); + end(); + return; + } setupStartEndListeners(); + int numTransitions = mTransitions.size(); if (!mPlayTogether) { // Setup sequence with listeners // TODO: Need to add listeners in such a way that we can remove them later if canceled - for (int i = 1; i < mTransitions.size(); ++i) { + for (int i = 1; i < numTransitions; ++i) { Transition previousTransition = mTransitions.get(i - 1); final Transition nextTransition = mTransitions.get(i); previousTransition.addListener(new TransitionListenerAdapter() { @@ -439,8 +458,8 @@ public class TransitionSet extends Transition { firstTransition.runAnimators(); } } else { - for (Transition childTransition : mTransitions) { - childTransition.runAnimators(); + for (int i = 0; i < numTransitions; ++i) { + mTransitions.get(i).runAnimators(); } } } diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java index 82c5425..eb8f3bf 100644 --- a/core/java/android/view/View.java +++ b/core/java/android/view/View.java @@ -4299,6 +4299,8 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * </p> * * @param a the styled attributes set to initialize the fading edges from + * + * @removed */ protected void initializeFadingEdge(TypedArray a) { // This method probably shouldn't have been included in the SDK to begin with. @@ -4439,6 +4441,8 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * </p> * * @param a the styled attributes set to initialize the scrollbars from + * + * @removed */ protected void initializeScrollbars(TypedArray a) { // It's not safe to use this method from apps. The parameter 'a' must have been obtained diff --git a/core/java/android/view/Window.java b/core/java/android/view/Window.java index ebc683a..63ab7d2 100644 --- a/core/java/android/view/Window.java +++ b/core/java/android/view/Window.java @@ -111,10 +111,19 @@ public abstract class Window { public static final int FEATURE_CONTENT_TRANSITIONS = 12; /** + * Enables Activities to run Activity Transitions either through sending or receiving + * ActivityOptions bundle created with + * {@link android.app.ActivityOptions#makeSceneTransitionAnimation(android.app.Activity, + * android.util.Pair[])} or {@link android.app.ActivityOptions#makeSceneTransitionAnimation( + * android.app.Activity, View, String)}. + */ + public static final int FEATURE_ACTIVITY_TRANSITIONS = 13; + + /** * Max value used as a feature ID * @hide */ - public static final int FEATURE_MAX = FEATURE_CONTENT_TRANSITIONS; + public static final int FEATURE_MAX = FEATURE_ACTIVITY_TRANSITIONS; /** Flag for setting the progress bar's visibility to VISIBLE */ public static final int PROGRESS_VISIBILITY_ON = -1; @@ -1459,7 +1468,7 @@ public abstract class Window { * have {@link ViewGroup#isTransitionGroup} return true. Typical Transitions will extend * {@link android.transition.Visibility} as exiting is governed by changing visibility * from {@link View#VISIBLE} to {@link View#INVISIBLE}. If transition is null, the views will - * remain unaffected. Requires {@link #FEATURE_CONTENT_TRANSITIONS}. + * remain unaffected. Requires {@link #FEATURE_ACTIVITY_TRANSITIONS}. * * @param transition The Transition to use to move Views out of the scene when calling a * new Activity. @@ -1475,7 +1484,7 @@ public abstract class Window { * visibility from {@link View#VISIBLE} to {@link View#INVISIBLE}. If transition is null, * the views will remain unaffected. If nothing is set, the default will be to use the same * transition as {@link #setExitTransition(android.transition.Transition)}. - * Requires {@link #FEATURE_CONTENT_TRANSITIONS}. + * Requires {@link #FEATURE_ACTIVITY_TRANSITIONS}. * * @param transition The Transition to use to move Views into the scene when reentering from a * previously-started Activity. @@ -1489,7 +1498,7 @@ public abstract class Window { * {@link ViewGroup#isTransitionGroup} return true. Typical Transitions will extend * {@link android.transition.Visibility} as entering is governed by changing visibility from * {@link View#INVISIBLE} to {@link View#VISIBLE}. If <code>transition</code> is null, - * entering Views will remain unaffected. Requires {@link #FEATURE_CONTENT_TRANSITIONS}. + * entering Views will remain unaffected. Requires {@link #FEATURE_ACTIVITY_TRANSITIONS}. * * @return the Transition to use to move Views into the initial Scene. * @attr ref android.R.styleable#Window_windowEnterTransition @@ -1517,7 +1526,7 @@ public abstract class Window { * have {@link ViewGroup#isTransitionGroup} return true. Typical Transitions will extend * {@link android.transition.Visibility} as exiting is governed by changing visibility * from {@link View#VISIBLE} to {@link View#INVISIBLE}. If transition is null, the views will - * remain unaffected. Requires {@link #FEATURE_CONTENT_TRANSITIONS}. + * remain unaffected. Requires {@link #FEATURE_ACTIVITY_TRANSITIONS}. * * @return the Transition to use to move Views out of the scene when calling a * new Activity. @@ -1531,7 +1540,7 @@ public abstract class Window { * or ViewGroups that have {@link ViewGroup#isTransitionGroup} return true. Typical Transitions * will extend {@link android.transition.Visibility} as exiting is governed by changing * visibility from {@link View#VISIBLE} to {@link View#INVISIBLE}. - * Requires {@link #FEATURE_CONTENT_TRANSITIONS}. + * Requires {@link #FEATURE_ACTIVITY_TRANSITIONS}. * * @return The Transition to use to move Views into the scene when reentering from a * previously-started Activity. @@ -1544,7 +1553,7 @@ public abstract class Window { * Scene. Typical Transitions will affect size and location, such as * {@link android.transition.ChangeBounds}. A null * value will cause transferred shared elements to blink to the final position. - * Requires {@link #FEATURE_CONTENT_TRANSITIONS}. + * Requires {@link #FEATURE_ACTIVITY_TRANSITIONS}. * * @param transition The Transition to use for shared elements transferred into the content * Scene. @@ -1559,7 +1568,7 @@ public abstract class Window { * value will cause transferred shared elements to blink to the final position. * If no value is set, the default will be to use the same value as * {@link #setSharedElementEnterTransition(android.transition.Transition)}. - * Requires {@link #FEATURE_CONTENT_TRANSITIONS}. + * Requires {@link #FEATURE_ACTIVITY_TRANSITIONS}. * * @param transition The Transition to use for shared elements transferred out of the content * Scene. @@ -1569,7 +1578,7 @@ public abstract class Window { /** * Returns the Transition that will be used for shared elements transferred into the content - * Scene. Requires {@link #FEATURE_CONTENT_TRANSITIONS}. + * Scene. Requires {@link #FEATURE_ACTIVITY_TRANSITIONS}. * * @return Transition to use for sharend elements transferred into the content Scene. * @attr ref android.R.styleable#Window_windowSharedElementEnterTransition @@ -1578,7 +1587,7 @@ public abstract class Window { /** * Returns the Transition that will be used for shared elements transferred back to a - * calling Activity. Requires {@link #FEATURE_CONTENT_TRANSITIONS}. + * calling Activity. Requires {@link #FEATURE_ACTIVITY_TRANSITIONS}. * * @return Transition to use for sharend elements transferred into the content Scene. * @attr ref android.R.styleable#Window_windowSharedElementReturnTransition @@ -1590,7 +1599,7 @@ public abstract class Window { * before the shared elements are transferred to the called Activity. If the shared elements * must animate during the exit transition, this Transition should be used. Upon completion, * the shared elements may be transferred to the started Activity. - * Requires {@link #FEATURE_CONTENT_TRANSITIONS}. + * Requires {@link #FEATURE_ACTIVITY_TRANSITIONS}. * * @param transition The Transition to use for shared elements in the launching Window * prior to transferring to the launched Activity's Window. @@ -1603,7 +1612,7 @@ public abstract class Window { * Activity after it has returned the shared element to it start location. If no value * is set, this will default to * {@link #setSharedElementExitTransition(android.transition.Transition)}. - * Requires {@link #FEATURE_CONTENT_TRANSITIONS}. + * Requires {@link #FEATURE_ACTIVITY_TRANSITIONS}. * * @param transition The Transition to use for shared elements in the launching Window * after the shared element has returned to the Window. @@ -1614,7 +1623,7 @@ public abstract class Window { /** * Returns the Transition to use for shared elements in the launching Window prior * to transferring to the launched Activity's Window. - * Requires {@link #FEATURE_CONTENT_TRANSITIONS}. + * Requires {@link #FEATURE_ACTIVITY_TRANSITIONS}. * * @return the Transition to use for shared elements in the launching Window prior * to transferring to the launched Activity's Window. @@ -1625,7 +1634,7 @@ public abstract class Window { /** * Returns the Transition that will be used for shared elements reentering from a started * Activity after it has returned the shared element to it start location. - * Requires {@link #FEATURE_CONTENT_TRANSITIONS}. + * Requires {@link #FEATURE_ACTIVITY_TRANSITIONS}. * * @return the Transition that will be used for shared elements reentering from a started * Activity after it has returned the shared element to it start location. @@ -1703,7 +1712,7 @@ public abstract class Window { * Returns the duration, in milliseconds, of the window background fade * when transitioning into or away from an Activity when called with an Activity Transition. * <p>When executing the enter transition, the background starts transparent - * and fades in. This requires {@link #FEATURE_CONTENT_TRANSITIONS}. The default is + * and fades in. This requires {@link #FEATURE_ACTIVITY_TRANSITIONS}. The default is * 300 milliseconds.</p> * * @return The duration of the window background fade to opaque during enter transition. @@ -1716,7 +1725,7 @@ public abstract class Window { * Sets the duration, in milliseconds, of the window background fade * when transitioning into or away from an Activity when called with an Activity Transition. * <p>When executing the enter transition, the background starts transparent - * and fades in. This requires {@link #FEATURE_CONTENT_TRANSITIONS}. The default is + * and fades in. This requires {@link #FEATURE_ACTIVITY_TRANSITIONS}. The default is * 300 milliseconds.</p> * * @param fadeDurationMillis The duration of the window background fade to or from opaque diff --git a/core/java/android/view/WindowManagerPolicy.java b/core/java/android/view/WindowManagerPolicy.java index 2ed125d..fec7550 100644 --- a/core/java/android/view/WindowManagerPolicy.java +++ b/core/java/android/view/WindowManagerPolicy.java @@ -638,6 +638,11 @@ public interface WindowManagerPolicy { public boolean canBeForceHidden(WindowState win, WindowManager.LayoutParams attrs); /** + * Return the window that is hiding the keyguard, if such a thing exists. + */ + public WindowState getWinShowWhenLockedLw(); + + /** * Called when the system would like to show a UI to indicate that an * application is starting. You can use this to add a * APPLICATION_STARTING_TYPE window with the given appToken to the window diff --git a/core/java/android/view/inputmethod/BaseInputConnection.java b/core/java/android/view/inputmethod/BaseInputConnection.java index 20adfe4..ba5d6c2 100644 --- a/core/java/android/view/inputmethod/BaseInputConnection.java +++ b/core/java/android/view/inputmethod/BaseInputConnection.java @@ -436,14 +436,6 @@ public class BaseInputConnection implements InputConnection { } /** - * The default implementation does nothing. - * @removed - */ - public final boolean requestUpdateCursorAnchorInfo(int cursorUpdateMode) { - return false; - } - - /** * The default implementation places the given text into the editable, * replacing any existing composing text. The new text is marked as * in a composing state with the composing style. diff --git a/core/java/android/view/inputmethod/CursorAnchorInfo.java b/core/java/android/view/inputmethod/CursorAnchorInfo.java index 600fffe..fd73432 100644 --- a/core/java/android/view/inputmethod/CursorAnchorInfo.java +++ b/core/java/android/view/inputmethod/CursorAnchorInfo.java @@ -120,38 +120,6 @@ public final class CursorAnchorInfo implements Parcelable { */ public static final int FLAG_IS_RTL = 0x04; - /** - * @removed - */ - public static final int CHARACTER_RECT_TYPE_MASK = 0x0f; - /** - * Type for {@link #CHARACTER_RECT_TYPE_MASK}: the editor did not specify any type of this - * character. Editor authors should not use this flag. - * @removed - */ - public static final int CHARACTER_RECT_TYPE_UNSPECIFIED = 0; - /** - * Type for {@link #CHARACTER_RECT_TYPE_MASK}: the character is entirely visible. - * @removed - */ - public static final int CHARACTER_RECT_TYPE_FULLY_VISIBLE = 1; - /** - * Type for {@link #CHARACTER_RECT_TYPE_MASK}: some area of the character is invisible. - * @removed - */ - public static final int CHARACTER_RECT_TYPE_PARTIALLY_VISIBLE = 2; - /** - * Type for {@link #CHARACTER_RECT_TYPE_MASK}: the character is entirely invisible. - * @removed - */ - public static final int CHARACTER_RECT_TYPE_INVISIBLE = 3; - /** - * Type for {@link #CHARACTER_RECT_TYPE_MASK}: the editor gave up to calculate the rectangle - * for this character. Input method authors should ignore the returned rectangle. - * @removed - */ - public static final int CHARACTER_RECT_TYPE_NOT_FEASIBLE = 4; - public CursorAnchorInfo(final Parcel source) { mSelectionStart = source.readInt(); mSelectionEnd = source.readInt(); @@ -318,20 +286,6 @@ public final class CursorAnchorInfo implements Parcelable { } /** - * @removed - */ - public Builder setInsertionMarkerLocation(final float horizontalPosition, - final float lineTop, final float lineBaseline, final float lineBottom, - final boolean clipped){ - mInsertionMarkerHorizontal = horizontalPosition; - mInsertionMarkerTop = lineTop; - mInsertionMarkerBaseline = lineBaseline; - mInsertionMarkerBottom = lineBottom; - mInsertionMarkerFlags = clipped ? FLAG_HAS_INVISIBLE_REGION : 0; - return this; - } - - /** * Sets the location of the text insertion point (zero width cursor) as a rectangle in * local coordinates. Calling this can be skipped when there is no text insertion point; * however if there is an insertion point, editors must call this method. @@ -390,43 +344,6 @@ public final class CursorAnchorInfo implements Parcelable { } /** - * Adds the bounding box of the character specified with the index. - * - * @param index index of the character in Java chars units. Must be specified in - * ascending order across successive calls. - * @param leadingEdgeX x coordinate of the leading edge of the character in local - * coordinates, that is, left edge for LTR text and right edge for RTL text. - * @param leadingEdgeY y coordinate of the leading edge of the character in local - * coordinates. - * @param trailingEdgeX x coordinate of the trailing edge of the character in local - * coordinates, that is, right edge for LTR text and left edge for RTL text. - * @param trailingEdgeY y coordinate of the trailing edge of the character in local - * coordinates. - * @param flags flags for this character rect. See {@link #FLAG_HAS_VISIBLE_REGION} for - * example. - * @throws IllegalArgumentException If the index is a negative value, or not greater than - * all of the previously called indices. - * @removed - */ - public Builder addCharacterRect(final int index, final float leadingEdgeX, - final float leadingEdgeY, final float trailingEdgeX, final float trailingEdgeY, - final int flags) { - final int newFlags; - final float left; - final float right; - if (leadingEdgeX <= trailingEdgeX) { - newFlags = flags; - left = leadingEdgeX; - right = trailingEdgeX; - } else { - newFlags = flags | FLAG_IS_RTL; - left = trailingEdgeX; - right = leadingEdgeX; - } - return addCharacterBounds(index, left, leadingEdgeY, right, trailingEdgeY, newFlags); - } - - /** * Sets the matrix that transforms local coordinates into screen coordinates. * @param matrix transformation matrix from local coordinates into screen coordinates. null * is interpreted as an identity matrix. @@ -538,15 +455,6 @@ public final class CursorAnchorInfo implements Parcelable { } /** - * Returns the visibility of the insertion marker. - * @return {@code true} if the insertion marker is partially or entirely clipped. - * @removed - */ - public boolean isInsertionMarkerClipped() { - return (mInsertionMarkerFlags & FLAG_HAS_VISIBLE_REGION) != 0; - } - - /** * Returns the horizontal start of the insertion marker, in the local coordinates that will * be transformed with {@link #getMatrix()} when rendered on the screen. * @return x coordinate that is compatible with {@link Layout#getPrimaryHorizontal(int)}. @@ -602,25 +510,6 @@ public final class CursorAnchorInfo implements Parcelable { } /** - * Returns a new instance of {@link RectF} that indicates the location of the character - * specified with the index. - * <p> - * Note that coordinates are not necessarily contiguous or even monotonous, especially when - * RTL text and LTR text are mixed. - * </p> - * @param index index of the character in a Java chars. - * @return a new instance of {@link RectF} that represents the location of the character in - * local coordinates. null if the character is invisible or the application did not provide - * the location. Note that the {@code left} field can be greater than the {@code right} field - * if the character is in RTL text. Returns {@code null} if no location information is - * available. - * @removed - */ - public RectF getCharacterRect(final int index) { - return getCharacterBounds(index); - } - - /** * Returns the flags associated with the character bounds specified with the index. * @param index index of the character in a Java chars. * @return {@code 0} if no flag is specified. @@ -633,16 +522,6 @@ public final class CursorAnchorInfo implements Parcelable { } /** - * Returns the flags associated with the character rect specified with the index. - * @param index index of the character in a Java chars. - * @return {@code 0} if no flag is specified. - * @removed - */ - public int getCharacterRectFlags(final int index) { - return getCharacterBoundsFlags(index); - } - - /** * Returns a new instance of {@link android.graphics.Matrix} that indicates the transformation * matrix that is to be applied other positional data in this class. * @return a new instance (copy) of the transformation matrix. diff --git a/core/java/android/view/inputmethod/InputConnection.java b/core/java/android/view/inputmethod/InputConnection.java index 093fb2f..c51d8a7 100644 --- a/core/java/android/view/inputmethod/InputConnection.java +++ b/core/java/android/view/inputmethod/InputConnection.java @@ -756,19 +756,4 @@ public interface InputConnection { * {@link InputMethodManager#updateCursorAnchorInfo(android.view.View, CursorAnchorInfo)}. */ public boolean requestCursorUpdates(int cursorUpdateMode); - - /** - * @removed - */ - public static final int REQUEST_UPDATE_CURSOR_UPDATE_IMMEDIATE = 1 << 0; - - /** - * @removed - */ - public static final int REQUEST_UPDATE_CURSOR_ANCHOR_INFO_MONITOR = 1 << 1; - - /** - * @removed - */ - public boolean requestUpdateCursorAnchorInfo(int cursorUpdateMode); } diff --git a/core/java/android/view/inputmethod/InputConnectionWrapper.java b/core/java/android/view/inputmethod/InputConnectionWrapper.java index 87853de..231aa07 100644 --- a/core/java/android/view/inputmethod/InputConnectionWrapper.java +++ b/core/java/android/view/inputmethod/InputConnectionWrapper.java @@ -129,11 +129,4 @@ public class InputConnectionWrapper implements InputConnection { public boolean requestCursorUpdates(int cursorUpdateMode) { return mTarget.requestCursorUpdates(cursorUpdateMode); } - - /** - * @removed - */ - public final boolean requestUpdateCursorAnchorInfo(int cursorUpdateMode) { - return mTarget.requestCursorUpdates(cursorUpdateMode); - } } diff --git a/core/java/android/widget/AbsListView.java b/core/java/android/widget/AbsListView.java index 94d52d5..3859e48 100644 --- a/core/java/android/widget/AbsListView.java +++ b/core/java/android/widget/AbsListView.java @@ -5721,14 +5721,6 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te public boolean requestCursorUpdates(int cursorUpdateMode) { return getTarget().requestCursorUpdates(cursorUpdateMode); } - - /** - * @removed - */ - @Override - public boolean requestUpdateCursorAnchorInfo(int cursorUpdateMode) { - return getTarget().requestCursorUpdates(cursorUpdateMode); - } } /** diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java index a81ff97..1509e80 100644 --- a/core/java/android/widget/TextView.java +++ b/core/java/android/widget/TextView.java @@ -8178,6 +8178,8 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener * Returns the TextView_textColor attribute from the TypedArray, if set, or * the TextAppearance_textColor from the TextView_textAppearance attribute, * if TextView_textColor was not set directly. + * + * @removed */ public static ColorStateList getTextColors(Context context, TypedArray attrs) { // It's not safe to use this method from apps. The parameter 'attrs' @@ -8205,6 +8207,8 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener * AttributeSet, if set, or the default color from the * TextAppearance_textColor from the TextView_textAppearance attribute, if * TextView_textColor was not set directly. + * + * @removed */ public static int getTextColor(Context context, TypedArray attrs, int def) { final ColorStateList colors = getTextColors(context, attrs); diff --git a/core/java/android/widget/Toolbar.java b/core/java/android/widget/Toolbar.java index be28199..ba2d5b8 100644 --- a/core/java/android/widget/Toolbar.java +++ b/core/java/android/widget/Toolbar.java @@ -37,7 +37,6 @@ import android.view.View; import android.view.ViewGroup; import com.android.internal.R; -import com.android.internal.app.ToolbarActionBar; import com.android.internal.view.menu.MenuBuilder; import com.android.internal.view.menu.MenuItemImpl; import com.android.internal.view.menu.MenuPresenter; @@ -1007,8 +1006,15 @@ public class Toolbar extends ViewGroup { } private void addSystemView(View v) { - final LayoutParams lp = new LayoutParams(LayoutParams.WRAP_CONTENT, - LayoutParams.WRAP_CONTENT); + final ViewGroup.LayoutParams vlp = v.getLayoutParams(); + final LayoutParams lp; + if (vlp == null) { + lp = generateDefaultLayoutParams(); + } else if (!checkLayoutParams(vlp)) { + lp = generateLayoutParams(vlp); + } else { + lp = (LayoutParams) vlp; + } lp.mViewType = LayoutParams.SYSTEM; addView(v, lp); } @@ -1280,27 +1286,36 @@ public class Toolbar extends ViewGroup { final int[] collapsingMargins = mTempMargins; collapsingMargins[0] = collapsingMargins[1] = 0; + // Align views within the minimum toolbar height, if set. + final int alignmentHeight = getMinimumHeight(); + if (shouldLayout(mNavButtonView)) { if (isRtl) { - right = layoutChildRight(mNavButtonView, right, collapsingMargins); + right = layoutChildRight(mNavButtonView, right, collapsingMargins, + alignmentHeight); } else { - left = layoutChildLeft(mNavButtonView, left, collapsingMargins); + left = layoutChildLeft(mNavButtonView, left, collapsingMargins, + alignmentHeight); } } if (shouldLayout(mCollapseButtonView)) { if (isRtl) { - right = layoutChildRight(mCollapseButtonView, right, collapsingMargins); + right = layoutChildRight(mCollapseButtonView, right, collapsingMargins, + alignmentHeight); } else { - left = layoutChildLeft(mCollapseButtonView, left, collapsingMargins); + left = layoutChildLeft(mCollapseButtonView, left, collapsingMargins, + alignmentHeight); } } if (shouldLayout(mMenuView)) { if (isRtl) { - left = layoutChildLeft(mMenuView, left, collapsingMargins); + left = layoutChildLeft(mMenuView, left, collapsingMargins, + alignmentHeight); } else { - right = layoutChildRight(mMenuView, right, collapsingMargins); + right = layoutChildRight(mMenuView, right, collapsingMargins, + alignmentHeight); } } @@ -1311,17 +1326,21 @@ public class Toolbar extends ViewGroup { if (shouldLayout(mExpandedActionView)) { if (isRtl) { - right = layoutChildRight(mExpandedActionView, right, collapsingMargins); + right = layoutChildRight(mExpandedActionView, right, collapsingMargins, + alignmentHeight); } else { - left = layoutChildLeft(mExpandedActionView, left, collapsingMargins); + left = layoutChildLeft(mExpandedActionView, left, collapsingMargins, + alignmentHeight); } } if (shouldLayout(mLogoView)) { if (isRtl) { - right = layoutChildRight(mLogoView, right, collapsingMargins); + right = layoutChildRight(mLogoView, right, collapsingMargins, + alignmentHeight); } else { - left = layoutChildLeft(mLogoView, left, collapsingMargins); + left = layoutChildLeft(mLogoView, left, collapsingMargins, + alignmentHeight); } } @@ -1434,13 +1453,15 @@ public class Toolbar extends ViewGroup { addCustomViewsWithGravity(mTempViews, Gravity.LEFT); final int leftViewsCount = mTempViews.size(); for (int i = 0; i < leftViewsCount; i++) { - left = layoutChildLeft(mTempViews.get(i), left, collapsingMargins); + left = layoutChildLeft(mTempViews.get(i), left, collapsingMargins, + alignmentHeight); } addCustomViewsWithGravity(mTempViews, Gravity.RIGHT); final int rightViewsCount = mTempViews.size(); for (int i = 0; i < rightViewsCount; i++) { - right = layoutChildRight(mTempViews.get(i), right, collapsingMargins); + right = layoutChildRight(mTempViews.get(i), right, collapsingMargins, + alignmentHeight); } // Centered views try to center with respect to the whole bar, but views pinned @@ -1459,8 +1480,10 @@ public class Toolbar extends ViewGroup { final int centerViewsCount = mTempViews.size(); for (int i = 0; i < centerViewsCount; i++) { - centerLeft = layoutChildLeft(mTempViews.get(i), centerLeft, collapsingMargins); + centerLeft = layoutChildLeft(mTempViews.get(i), centerLeft, collapsingMargins, + alignmentHeight); } + mTempViews.clear(); } @@ -1483,46 +1506,49 @@ public class Toolbar extends ViewGroup { return width; } - private int layoutChildLeft(View child, int left, int[] collapsingMargins) { + private int layoutChildLeft(View child, int left, int[] collapsingMargins, + int alignmentHeight) { final LayoutParams lp = (LayoutParams) child.getLayoutParams(); final int l = lp.leftMargin - collapsingMargins[0]; left += Math.max(0, l); collapsingMargins[0] = Math.max(0, -l); - final int top = getChildTop(child); + final int top = getChildTop(child, alignmentHeight); final int childWidth = child.getMeasuredWidth(); child.layout(left, top, left + childWidth, top + child.getMeasuredHeight()); left += childWidth + lp.rightMargin; return left; } - private int layoutChildRight(View child, int right, int[] collapsingMargins) { + private int layoutChildRight(View child, int right, int[] collapsingMargins, + int alignmentHeight) { final LayoutParams lp = (LayoutParams) child.getLayoutParams(); final int r = lp.rightMargin - collapsingMargins[1]; right -= Math.max(0, r); collapsingMargins[1] = Math.max(0, -r); - final int top = getChildTop(child); + final int top = getChildTop(child, alignmentHeight); final int childWidth = child.getMeasuredWidth(); child.layout(right - childWidth, top, right, top + child.getMeasuredHeight()); right -= childWidth + lp.leftMargin; return right; } - private int getChildTop(View child) { + private int getChildTop(View child, int alignmentHeight) { final LayoutParams lp = (LayoutParams) child.getLayoutParams(); + final int childHeight = child.getMeasuredHeight(); + final int alignmentOffset = alignmentHeight > 0 ? (childHeight - alignmentHeight) / 2 : 0; switch (getChildVerticalGravity(lp.gravity)) { case Gravity.TOP: - return getPaddingTop(); + return getPaddingTop() - alignmentOffset; case Gravity.BOTTOM: - return getHeight() - getPaddingBottom() - - child.getMeasuredHeight() - lp.bottomMargin; + return getHeight() - getPaddingBottom() - childHeight + - lp.bottomMargin - alignmentOffset; default: case Gravity.CENTER_VERTICAL: final int paddingTop = getPaddingTop(); final int paddingBottom = getPaddingBottom(); final int height = getHeight(); - final int childHeight = child.getMeasuredHeight(); final int space = height - paddingTop - paddingBottom; int spaceAbove = (space - childHeight) / 2; if (spaceAbove < lp.topMargin) { diff --git a/core/java/com/android/internal/app/ToolbarActionBar.java b/core/java/com/android/internal/app/ToolbarActionBar.java index 99c87ea..4410f25 100644 --- a/core/java/com/android/internal/app/ToolbarActionBar.java +++ b/core/java/com/android/internal/app/ToolbarActionBar.java @@ -22,7 +22,6 @@ import android.app.ActionBar; import android.content.Context; import android.content.res.Configuration; import android.graphics.drawable.Drawable; -import android.text.TextUtils; import android.view.ActionMode; import android.view.KeyEvent; import android.view.LayoutInflater; @@ -33,7 +32,6 @@ import android.view.Window; import android.view.WindowCallbackWrapper; import android.widget.SpinnerAdapter; import android.widget.Toolbar; -import com.android.internal.R; import com.android.internal.view.menu.MenuBuilder; import com.android.internal.view.menu.MenuPresenter; import com.android.internal.widget.DecorToolbar; @@ -48,8 +46,6 @@ public class ToolbarActionBar extends ActionBar { private Window.Callback mWindowCallback; private boolean mMenuCallbackSet; - private CharSequence mHomeDescription; - private boolean mLastMenuVisibility; private ArrayList<OnMenuVisibilityListener> mMenuVisibilityListeners = new ArrayList<OnMenuVisibilityListener>(); @@ -76,8 +72,6 @@ public class ToolbarActionBar extends ActionBar { mDecorToolbar.setWindowCallback(mWindowCallback); toolbar.setOnMenuItemClickListener(mMenuClicker); mDecorToolbar.setWindowTitle(title); - mHomeDescription = mToolbar.getNavigationContentDescription(); - updateNavDescription(); } public Window.Callback getWrappedWindowCallback() { @@ -168,8 +162,7 @@ public class ToolbarActionBar extends ActionBar { @Override public void setHomeActionContentDescription(CharSequence description) { - mToolbar.setNavigationContentDescription(description); - mHomeDescription = description; + mDecorToolbar.setNavigationContentDescription(description); } @Override @@ -179,8 +172,7 @@ public class ToolbarActionBar extends ActionBar { @Override public void setHomeActionContentDescription(int resId) { - mToolbar.setNavigationContentDescription(resId); - mHomeDescription = mToolbar.getNavigationContentDescription(); + mDecorToolbar.setNavigationContentDescription(resId); } @Override @@ -258,21 +250,7 @@ public class ToolbarActionBar extends ActionBar { @Override public void setDisplayOptions(@DisplayOptions int options, @DisplayOptions int mask) { final int currentOptions = mDecorToolbar.getDisplayOptions(); - final int changed = (options ^ currentOptions) & mask; mDecorToolbar.setDisplayOptions(options & mask | currentOptions & ~mask); - if ((changed & ActionBar.DISPLAY_HOME_AS_UP) != 0) { - updateNavDescription(); - } - } - - private void updateNavDescription() { - if ((mDecorToolbar.getDisplayOptions() & ActionBar.DISPLAY_HOME_AS_UP) != 0) { - if (TextUtils.isEmpty(mHomeDescription)) { - mToolbar.setNavigationContentDescription(R.string.action_bar_up_description); - } else { - mToolbar.setNavigationContentDescription(mHomeDescription); - } - } } @Override diff --git a/core/java/com/android/internal/os/ZygoteInit.java b/core/java/com/android/internal/os/ZygoteInit.java index 0aee0e3..40c9ed2 100644 --- a/core/java/com/android/internal/os/ZygoteInit.java +++ b/core/java/com/android/internal/os/ZygoteInit.java @@ -254,12 +254,20 @@ public class ZygoteInit { preloadClasses(); preloadResources(); preloadOpenGL(); + preloadSharedLibraries(); // Ask the WebViewFactory to do any initialization that must run in the zygote process, // for memory sharing purposes. WebViewFactory.prepareWebViewInZygote(); Log.d(TAG, "end preload"); } + private static void preloadSharedLibraries() { + Log.i(TAG, "Preloading shared libraries..."); + System.loadLibrary("android"); + System.loadLibrary("compiler_rt"); + System.loadLibrary("jnigraphics"); + } + private static void preloadOpenGL() { if (!SystemProperties.getBoolean(PROPERTY_DISABLE_OPENGL_PRELOADING, false)) { EGL14.eglGetDisplay(EGL14.EGL_DEFAULT_DISPLAY); diff --git a/core/java/com/android/internal/util/UserIcons.java b/core/java/com/android/internal/util/UserIcons.java new file mode 100644 index 0000000..e1e9d5e --- /dev/null +++ b/core/java/com/android/internal/util/UserIcons.java @@ -0,0 +1,75 @@ +/* + * 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.internal.util; + +import android.content.res.Resources; +import android.graphics.Bitmap; +import android.graphics.Canvas; +import android.graphics.PorterDuff.Mode; +import android.graphics.drawable.Drawable; +import android.os.UserHandle; + +import com.android.internal.R; + +/** + * Helper class that generates default user icons. + */ +public class UserIcons { + + private static final int[] USER_ICON_COLORS = { + R.color.user_icon_1, + R.color.user_icon_2, + R.color.user_icon_3, + R.color.user_icon_4, + R.color.user_icon_5, + R.color.user_icon_6, + R.color.user_icon_7, + R.color.user_icon_8 + }; + + /** + * Converts a given drawable to a bitmap. + */ + public static Bitmap convertToBitmap(Drawable icon) { + if (icon == null) { + return null; + } + Bitmap bitmap = Bitmap.createBitmap(icon.getIntrinsicWidth(), icon.getIntrinsicHeight(), + Bitmap.Config.ARGB_8888); + icon.draw(new Canvas(bitmap)); + return bitmap; + } + + /** + * Returns a default user icon for the given user. + * + * Note that for guest users, you should pass in {@code UserHandle.USER_NULL}. + * @param userId the user id or {@code UserHandle.USER_NULL} for a non-user specific icon + * @param light whether we want a light icon (suitable for a dark background) + */ + public static Drawable getDefaultUserIcon(int userId, boolean light) { + int colorResId = light ? R.color.user_icon_default_white : R.color.user_icon_default_gray; + if (userId != UserHandle.USER_NULL) { + // Return colored icon instead + colorResId = USER_ICON_COLORS[userId % USER_ICON_COLORS.length]; + } + Drawable icon = Resources.getSystem().getDrawable(R.drawable.ic_account_circle).mutate(); + icon.setColorFilter(Resources.getSystem().getColor(colorResId), Mode.SRC_IN); + icon.setBounds(0, 0, icon.getIntrinsicWidth(), icon.getIntrinsicHeight()); + return icon; + } +} diff --git a/core/java/com/android/internal/view/InputConnectionWrapper.java b/core/java/com/android/internal/view/InputConnectionWrapper.java index 0c65ad1..7dc927f 100644 --- a/core/java/com/android/internal/view/InputConnectionWrapper.java +++ b/core/java/com/android/internal/view/InputConnectionWrapper.java @@ -445,11 +445,4 @@ public class InputConnectionWrapper implements InputConnection { } return result; } - - /** - * @removed - */ - public boolean requestUpdateCursorAnchorInfo(int cursorUpdateMode) { - return requestCursorUpdates(cursorUpdateMode); - } } diff --git a/core/java/com/android/internal/widget/ActionBarView.java b/core/java/com/android/internal/widget/ActionBarView.java index e53af69..fb44e58 100644 --- a/core/java/com/android/internal/widget/ActionBarView.java +++ b/core/java/com/android/internal/widget/ActionBarView.java @@ -135,6 +135,7 @@ public class ActionBarView extends AbsActionBarView implements DecorToolbar { private ExpandedActionViewMenuPresenter mExpandedMenuPresenter; View mExpandedActionView; + private int mDefaultUpDescription = R.string.action_bar_up_description; Window.Callback mWindowCallback; @@ -187,7 +188,7 @@ public class ActionBarView extends AbsActionBarView implements DecorToolbar { mExpandedHomeLayout.setShowUp(true); mExpandedHomeLayout.setOnClickListener(mExpandedActionViewUpListener); mExpandedHomeLayout.setContentDescription(getResources().getText( - R.string.action_bar_up_description)); + mDefaultUpDescription)); // This needs to highlight/be focusable on its own. // TODO: Clean up the handoff between expanded/normal. @@ -579,7 +580,7 @@ public class ActionBarView extends AbsActionBarView implements DecorToolbar { homeDesc = mHomeDescription; } else { if ((mDisplayOptions & ActionBar.DISPLAY_HOME_AS_UP) != 0) { - homeDesc = mContext.getResources().getText(R.string.action_bar_up_description); + homeDesc = mContext.getResources().getText(mDefaultUpDescription); } else { homeDesc = mContext.getResources().getText(R.string.action_bar_home_description); } @@ -1330,6 +1331,15 @@ public class ActionBarView extends AbsActionBarView implements DecorToolbar { updateHomeAccessibility(mUpGoerFive.isEnabled()); } + @Override + public void setDefaultNavigationContentDescription(int defaultNavigationContentDescription) { + if (mDefaultUpDescription == defaultNavigationContentDescription) { + return; + } + mDefaultUpDescription = defaultNavigationContentDescription; + updateHomeAccessibility(mUpGoerFive.isEnabled()); + } + static class SavedState extends BaseSavedState { int expandedMenuItemId; boolean isOverflowOpen; diff --git a/core/java/com/android/internal/widget/DecorToolbar.java b/core/java/com/android/internal/widget/DecorToolbar.java index 5281045..fee3015 100644 --- a/core/java/com/android/internal/widget/DecorToolbar.java +++ b/core/java/com/android/internal/widget/DecorToolbar.java @@ -89,6 +89,7 @@ public interface DecorToolbar { void setNavigationIcon(int resId); void setNavigationContentDescription(CharSequence description); void setNavigationContentDescription(int resId); + void setDefaultNavigationContentDescription(int defaultNavigationContentDescription); void saveHierarchyState(SparseArray<Parcelable> toolbarStates); void restoreHierarchyState(SparseArray<Parcelable> toolbarStates); } diff --git a/core/java/com/android/internal/widget/ToolbarWidgetWrapper.java b/core/java/com/android/internal/widget/ToolbarWidgetWrapper.java index 250bbac..8446e06 100644 --- a/core/java/com/android/internal/widget/ToolbarWidgetWrapper.java +++ b/core/java/com/android/internal/widget/ToolbarWidgetWrapper.java @@ -76,14 +76,21 @@ public class ToolbarWidgetWrapper implements DecorToolbar { private boolean mTitleSet; private CharSequence mTitle; private CharSequence mSubtitle; + private CharSequence mHomeDescription; private Window.Callback mWindowCallback; private boolean mMenuPrepared; private ActionMenuPresenter mActionMenuPresenter; private int mNavigationMode = ActionBar.NAVIGATION_MODE_STANDARD; + private int mDefaultNavigationContentDescription = 0; public ToolbarWidgetWrapper(Toolbar toolbar, boolean style) { + this(toolbar, style, R.string.action_bar_up_description); + } + + public ToolbarWidgetWrapper(Toolbar toolbar, boolean style, + int defaultNavigationContentDescription) { mToolbar = toolbar; mTitle = toolbar.getTitle(); @@ -166,10 +173,8 @@ public class ToolbarWidgetWrapper implements DecorToolbar { mDisplayOpts = detectDisplayOptions(); } - if (TextUtils.isEmpty(mToolbar.getNavigationContentDescription())) { - mToolbar.setNavigationContentDescription( - getContext().getResources().getText(R.string.action_bar_up_description)); - } + setDefaultNavigationContentDescription(defaultNavigationContentDescription); + mHomeDescription = mToolbar.getNavigationContentDescription(); mToolbar.setNavigationOnClickListener(new View.OnClickListener() { final ActionMenuItem mNavItem = new ActionMenuItem(mToolbar.getContext(), @@ -183,6 +188,17 @@ public class ToolbarWidgetWrapper implements DecorToolbar { }); } + @Override + public void setDefaultNavigationContentDescription(int defaultNavigationContentDescription) { + if (defaultNavigationContentDescription == mDefaultNavigationContentDescription) { + return; + } + mDefaultNavigationContentDescription = defaultNavigationContentDescription; + if (TextUtils.isEmpty(mToolbar.getNavigationContentDescription())) { + setNavigationContentDescription(mDefaultNavigationContentDescription); + } + } + private int detectDisplayOptions() { int opts = ActionBar.DISPLAY_SHOW_TITLE | ActionBar.DISPLAY_SHOW_HOME | ActionBar.DISPLAY_USE_LOGO; @@ -395,6 +411,7 @@ public class ToolbarWidgetWrapper implements DecorToolbar { if ((changed & ActionBar.DISPLAY_HOME_AS_UP) != 0) { if ((newOpts & ActionBar.DISPLAY_HOME_AS_UP) != 0) { mToolbar.setNavigationIcon(mNavIcon); + updateHomeAccessibility(); } else { mToolbar.setNavigationIcon(null); } @@ -602,12 +619,23 @@ public class ToolbarWidgetWrapper implements DecorToolbar { @Override public void setNavigationContentDescription(CharSequence description) { - mToolbar.setNavigationContentDescription(description); + mHomeDescription = description; + updateHomeAccessibility(); } @Override public void setNavigationContentDescription(int resId) { - mToolbar.setNavigationContentDescription(resId); + setNavigationContentDescription(resId == 0 ? null : getContext().getString(resId)); + } + + private void updateHomeAccessibility() { + if ((mDisplayOpts & ActionBar.DISPLAY_HOME_AS_UP) != 0) { + if (TextUtils.isEmpty(mHomeDescription)) { + mToolbar.setNavigationContentDescription(mDefaultNavigationContentDescription); + } else { + mToolbar.setNavigationContentDescription(mHomeDescription); + } + } } @Override diff --git a/core/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp index a63258c..1573106 100644 --- a/core/jni/AndroidRuntime.cpp +++ b/core/jni/AndroidRuntime.cpp @@ -271,6 +271,7 @@ AndroidRuntime::~AndroidRuntime() } void AndroidRuntime::setArgv0(const char* argv0) { + memset(mArgBlockStart, 0, mArgBlockLength); strlcpy(mArgBlockStart, argv0, mArgBlockLength); } @@ -345,28 +346,6 @@ static bool runtime_isSensitiveThread() { return state && state->getStrictModePolicy() != 0; } - -/** - * Add VM arguments to the to-be-executed VM - * Stops at first non '-' argument (also stops at an argument of '--') - * Returns the number of args consumed - */ -int AndroidRuntime::addVmArguments(int argc, const char* const argv[]) -{ - int i; - - for (i = 0; i<argc; i++) { - if (argv[i][0] != '-') { - return i; - } - if (argv[i][1] == '-' && argv[i][2] == 0) { - return i+1; - } - addOption(argv[i]); - } - return i; -} - static int hasDir(const char* dir) { struct stat s; diff --git a/core/jni/android/graphics/Path.cpp b/core/jni/android/graphics/Path.cpp index 6ef1d2c..9d3e74b 100644 --- a/core/jni/android/graphics/Path.cpp +++ b/core/jni/android/graphics/Path.cpp @@ -435,19 +435,32 @@ public: std::vector<float> lengths; float errorSquared = acceptableError * acceptableError; - while ((verb = pathIter.next(points)) != SkPath::kDone_Verb) { + while ((verb = pathIter.next(points, false)) != SkPath::kDone_Verb) { createVerbSegments(verb, points, segmentPoints, lengths, errorSquared); } if (segmentPoints.empty()) { - return NULL; + int numVerbs = path->countVerbs(); + if (numVerbs == 1) { + addMove(segmentPoints, lengths, path->getPoint(0)); + } else { + // Invalid or empty path. Fall back to point(0,0) + addMove(segmentPoints, lengths, SkPoint()); + } + } + + float totalLength = lengths.back(); + if (totalLength == 0) { + // Lone Move instructions should still be able to animate at the same value. + segmentPoints.push_back(segmentPoints.back()); + lengths.push_back(1); + totalLength = 1; } size_t numPoints = segmentPoints.size(); size_t approximationArraySize = numPoints * 3; float* approximation = new float[approximationArraySize]; - float totalLength = lengths.back(); int approximationIndex = 0; for (size_t i = 0; i < numPoints; i++) { diff --git a/packages/SystemUI/res/drawable/ic_account_circle.xml b/core/res/res/drawable/ic_account_circle.xml index d8649e5..a8c5b8c 100644 --- a/packages/SystemUI/res/drawable/ic_account_circle.xml +++ b/core/res/res/drawable/ic_account_circle.xml @@ -14,18 +14,11 @@ Copyright (C) 2014 The Android Open Source Project limitations under the License. --> <vector xmlns:android="http://schemas.android.com/apk/res/android" - android:width="24dp" - android:height="24dp" - android:viewportWidth="24.0" - android:viewportHeight="24.0"> - - <group - android:scaleX="1.2" - android:scaleY="1.2" - android:pivotX="12.0" - android:pivotY="12.0"> + android:width="48.0dp" + android:height="48.0dp" + android:viewportWidth="48.0" + android:viewportHeight="48.0"> <path - android:fillColor="#FFFFFFFF" - android:pathData="M12.0,2.0C6.5,2.0 2.0,6.5 2.0,12.0s4.5,10.0 10.0,10.0c5.5,0.0 10.0,-4.5 10.0,-10.0S17.5,2.0 12.0,2.0zM12.0,5.0c1.7,0.0 3.0,1.3 3.0,3.0c0.0,1.7 -1.3,3.0 -3.0,3.0c-1.7,0.0 -3.0,-1.3 -3.0,-3.0C9.0,6.3 10.3,5.0 12.0,5.0zM12.0,19.2c-2.5,0.0 -4.7,-1.3 -6.0,-3.2c0.0,-2.0 4.0,-3.1 6.0,-3.1c2.0,0.0 6.0,1.1 6.0,3.1C16.7,17.9 14.5,19.2 12.0,19.2z"/> - </group> + android:pathData="M24,0C10.8,0 0,10.8 0,24s10.8,24 24,24s24,-10.8 24,-24S37.200001,0 24,0zM24,7.2c3.96,0 7.2,3.24 7.2,7.2s-3.24,7.2 -7.2,7.2s-7.2,-3.24 -7.2,-7.2S20.040001,7.2 24,7.2zM24,41.279999c-6,0 -11.28,-3.12 -14.4,-7.68c0.12,-4.8 9.6,-7.44 14.4,-7.44s14.28,2.64 14.4,7.44C35.279999,38.16 30,41.279999 24,41.279999z" + android:fillColor="#FFFFFFFF"/> </vector> diff --git a/core/res/res/layout/alert_dialog_material.xml b/core/res/res/layout/alert_dialog_material.xml index be89e41..e5ef629 100644 --- a/core/res/res/layout/alert_dialog_material.xml +++ b/core/res/res/layout/alert_dialog_material.xml @@ -56,8 +56,7 @@ android:layout_height="wrap_content" android:layout_weight="1" android:orientation="vertical" - android:minHeight="64dp" - android:paddingTop="@dimen/alert_dialog_padding_top_material"> + android:minHeight="64dp"> <ScrollView android:id="@+id/scrollView" android:layout_width="match_parent" android:layout_height="wrap_content" @@ -67,6 +66,7 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:paddingStart="@dimen/alert_dialog_padding_material" + android:paddingTop="@dimen/alert_dialog_padding_top_material" android:paddingEnd="@dimen/alert_dialog_padding_material" /> </ScrollView> </LinearLayout> diff --git a/core/res/res/values-mcc234-mnc20/config.xml b/core/res/res/values-mcc234-mnc20/config.xml index 1ed53dc..619e517 100644 --- a/core/res/res/values-mcc234-mnc20/config.xml +++ b/core/res/res/values-mcc234-mnc20/config.xml @@ -21,6 +21,22 @@ for different hardware and product builds. --> <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <!-- Array of ConnectivityManager.TYPE_xxxx values allowable for tethering --> + <!-- Common options are [1, 4] for TYPE_WIFI and TYPE_MOBILE_DUN or + <!== [0,1,5,7] for TYPE_MOBILE, TYPE_WIFI, TYPE_MOBILE_HIPRI and TYPE_BLUETOOTH --> + <integer-array translatable="false" name="config_tether_upstream_types"> + <item>1</item> + <item>4</item> + <item>7</item> + <item>9</item> + </integer-array> + + <!-- String containing the apn value for tethering. May be overriden by secure settings + TETHER_DUN_APN. Value is a comma separated series of strings: + "name,apn,proxy,port,username,password,server,mmsc,mmsproxy,mmsport,mcc,mnc,auth,type" + note that empty fields can be ommitted: "name,apn,,,,,,,,,310,260,,DUN" --> + <string translatable="false" name="config_tether_apndata">3hotspot,3hotspot,,,,,,,,,234,20,0,DUN</string> + <!-- Configure mobile network MTU. Carrier specific value is set here. --> <integer name="config_mobile_mtu">1440</integer> diff --git a/core/res/res/values-mcc235-mnc94/config.xml b/core/res/res/values-mcc235-mnc94/config.xml index d602c9f..723af3d 100644 --- a/core/res/res/values-mcc235-mnc94/config.xml +++ b/core/res/res/values-mcc235-mnc94/config.xml @@ -21,6 +21,22 @@ for different hardware and product builds. --> <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <!-- Array of ConnectivityManager.TYPE_xxxx values allowable for tethering --> + <!-- Common options are [1, 4] for TYPE_WIFI and TYPE_MOBILE_DUN or + <!== [0,1,5,7] for TYPE_MOBILE, TYPE_WIFI, TYPE_MOBILE_HIPRI and TYPE_BLUETOOTH --> + <integer-array translatable="false" name="config_tether_upstream_types"> + <item>1</item> + <item>4</item> + <item>7</item> + <item>9</item> + </integer-array> + + <!-- String containing the apn value for tethering. May be overriden by secure settings + TETHER_DUN_APN. Value is a comma separated series of strings: + "name,apn,proxy,port,username,password,server,mmsc,mmsproxy,mmsport,mcc,mnc,auth,type" + note that empty fields can be ommitted: "name,apn,,,,,,,,,310,260,,DUN" --> + <string translatable="false" name="config_tether_apndata">3hotspot,3hotspot,,,,,,,,,235,94,0,DUN</string> + <!-- Configure mobile network MTU. Carrier specific value is set here. --> <integer name="config_mobile_mtu">1440</integer> diff --git a/core/res/res/values-mcc425-mnc01/config.xml b/core/res/res/values-mcc425-mnc01/config.xml deleted file mode 100644 index f4854da..0000000 --- a/core/res/res/values-mcc425-mnc01/config.xml +++ /dev/null @@ -1,40 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- -/* -** Copyright 2013, The Android Open Source Project -** -** Licensed under the Apache License, Version 2.0 (the "License"); -** you may not use this file except in compliance with the License. -** You my 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. -*/ ---> - -<!-- These resources are around just to allow their values to be customized - for different hardware and product builds. --> -<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - - <!-- Array of ConnectivityManager.TYPE_xxxx values allowable for tethering --> - <!-- Common options are [1, 4] for TYPE_WIFI and TYPE_MOBILE_DUN or - <!== [0,1,5,7] for TYPE_MOBILE, TYPE_WIFI, TYPE_MOBILE_HIPRI and TYPE_BLUETOOTH --> - <integer-array translatable="false" name="config_tether_upstream_types"> - <item>1</item> - <item>4</item> - <item>7</item> - <item>9</item> - </integer-array> - - <!-- String containing the apn value for tethering. May be overriden by secure settings - TETHER_DUN_APN. Value is a comma separated series of strings: - "name,apn,proxy,port,username,password,server,mmsc,mmsproxy,mmsport,mcc,mnc,auth,type" - note that empty fields can be ommitted: "name,apn,,,,,,,,,310,260,,DUN" --> - <string translatable="false" name="config_tether_apndata">DUN,modem.orange.net.il,,,,,,,,,425,01,,DUN</string> - -</resources> diff --git a/core/res/res/values-sw600dp-land/dimens_material.xml b/core/res/res/values-sw600dp-land/dimens_material.xml new file mode 100644 index 0000000..f8f16e2 --- /dev/null +++ b/core/res/res/values-sw600dp-land/dimens_material.xml @@ -0,0 +1,23 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2014 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<resources> + + <!-- Use the default title sizes on tablets. --> + <dimen name="text_size_title_material_toolbar">@dimen/text_size_title_material</dimen> + <!-- Use the default subtitle sizes on tablets. --> + <dimen name="text_size_subtitle_material_toolbar">@dimen/text_size_subhead_material</dimen> + +</resources> diff --git a/core/res/res/values-sw720dp/styles.xml b/core/res/res/values-sw720dp/styles.xml index fee1c24..94ec0a6 100644 --- a/core/res/res/values-sw720dp/styles.xml +++ b/core/res/res/values-sw720dp/styles.xml @@ -16,10 +16,9 @@ <resources> <style name="PreferencePanel"> - <item name="android:layout_marginStart">@dimen/preference_screen_side_margin</item> - <item name="android:layout_marginEnd">@dimen/preference_screen_side_margin</item> - <item name="android:layout_marginTop">@dimen/preference_screen_top_margin</item> - <item name="android:layout_marginBottom">@dimen/preference_screen_bottom_margin</item> - <item name="android:background">?attr/detailsElementBackground</item> + <item name="layout_marginStart">@dimen/preference_screen_side_margin</item> + <item name="layout_marginEnd">@dimen/preference_screen_side_margin</item> + <item name="layout_marginTop">@dimen/preference_screen_top_margin</item> + <item name="layout_marginBottom">@dimen/preference_screen_bottom_margin</item> </style> </resources> diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml index 13b1dd9..438d1fb 100644 --- a/core/res/res/values/attrs.xml +++ b/core/res/res/values/attrs.xml @@ -458,6 +458,10 @@ transitions between different window content. --> <attr name="windowContentTransitionManager" format="reference" /> + <!-- Flag indicating whether this window allows Activity Transitions. + Corresponds to {@link android.view.Window#FEATURE_ACTIVITY_TRANSITIONS}. --> + <attr name="windowActivityTransitions" format="boolean" /> + <!-- Reference to a Transition XML resource defining the desired Transition used to move Views into the initial Window's content Scene. Corresponds to {@link android.view.Window#setEnterTransition(android.transition.Transition)}. --> @@ -1792,6 +1796,7 @@ <attr name="windowTranslucentNavigation" /> <attr name="windowSwipeToDismiss" /> <attr name="windowContentTransitions" /> + <attr name="windowActivityTransitions" /> <attr name="windowContentTransitionManager" /> <attr name="windowActionBarFullscreenDecorLayout" /> diff --git a/core/res/res/values/colors.xml b/core/res/res/values/colors.xml index c42683b..5a7e168 100644 --- a/core/res/res/values/colors.xml +++ b/core/res/res/values/colors.xml @@ -147,5 +147,16 @@ <color name="system_notification_accent_color">#ff607D8B</color> <color name="battery_saver_mode_color">#fff4511e</color><!-- deep orange 600 --> + <!-- Default user icon colors --> + <color name="user_icon_1">#ffe91e63</color><!-- pink 500 --> + <color name="user_icon_2">#ff3f51b5</color><!-- indigo 500 --> + <color name="user_icon_3">#ff4285f4</color><!-- blue 500 --> + <color name="user_icon_4">#ff00bcd4</color><!-- teal 500 --> + <color name="user_icon_5">#ff0f9d58</color><!-- green 500 --> + <color name="user_icon_6">#ff8bc34a</color><!-- light green 500 --> + <color name="user_icon_7">#ffff9800</color><!-- orange 500 --> + <color name="user_icon_8">#ffff5722</color><!-- deep orange 500 --> + <color name="user_icon_default_gray">#ff9e9e9e</color><!-- gray 500 --> + <color name="user_icon_default_white">#ffffffff</color><!-- white --> </resources> diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml index ee699ed..3907fc5 100644 --- a/core/res/res/values/config.xml +++ b/core/res/res/values/config.xml @@ -360,6 +360,9 @@ <!-- Boolean indicating associated network selection is allowed --> <bool translatable="false" name="config_wifi_framework_enable_associated_network_selection">true</bool> + <!-- Boolean indicating that wifi only link configuratios that have exact same credentials (i.e PSK) --> + <bool translatable="false" name="config_wifi_only_link_same_credential_configurations">true</bool> + <!-- Wifi driver stop delay, in milliseconds. Default value is 2 minutes. --> <integer translatable="false" name="config_wifi_driver_stop_delay">120000</integer> diff --git a/core/res/res/values/dimens_material.xml b/core/res/res/values/dimens_material.xml index 275a5ec..3e64f30 100644 --- a/core/res/res/values/dimens_material.xml +++ b/core/res/res/values/dimens_material.xml @@ -41,11 +41,11 @@ <dimen name="text_size_headline_material">24sp</dimen> <dimen name="text_size_title_material">20sp</dimen> <dimen name="text_size_subhead_material">16sp</dimen> - <dimen name="text_size_title_material_toolbar">20dp</dimen> - <dimen name="text_size_subtitle_material_toolbar">16dp</dimen> + <dimen name="text_size_title_material_toolbar">@dimen/text_size_title_material</dimen> + <dimen name="text_size_subtitle_material_toolbar">@dimen/text_size_subhead_material</dimen> <dimen name="text_size_menu_material">16sp</dimen> - <dimen name="text_size_body_2_material">14sp</dimen> - <dimen name="text_size_body_1_material">14sp</dimen> + <dimen name="text_size_body_2_material">16sp</dimen> + <dimen name="text_size_body_1_material">16sp</dimen> <dimen name="text_size_caption_material">12sp</dimen> <dimen name="text_size_button_material">14sp</dimen> diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml index 38b1e13..99918a0 100644 --- a/core/res/res/values/public.xml +++ b/core/res/res/values/public.xml @@ -2293,6 +2293,7 @@ <public type="attr" name="patternPathData" /> <public type="attr" name="strokeAlpha" /> <public type="attr" name="fillAlpha" /> + <public type="attr" name="windowActivityTransitions" /> <public-padding type="dimen" name="l_resource_pad" end="0x01050010" /> @@ -2561,6 +2562,9 @@ <public type="style" name="Widget.Material.SearchView" /> <public type="style" name="Widget.Material.Light.SearchView" /> + <public type="style" name="Widget.Material.TimePicker" /> + <public type="style" name="Widget.Material.Light.TimePicker" /> + <public type="style" name="Widget.Material.Light.DatePicker" /> <public-padding type="string" name="l_resource_pad" end="0x01040030" /> diff --git a/core/res/res/values/styles_material.xml b/core/res/res/values/styles_material.xml index 26c7d10..836f886 100644 --- a/core/res/res/values/styles_material.xml +++ b/core/res/res/values/styles_material.xml @@ -851,10 +851,7 @@ please see styles_device_defaults.xml. <item name="src">@drawable/ic_menu_moreoverflow_material</item> <item name="background">?attr/actionBarItemBackground</item> <item name="contentDescription">@string/action_menu_overflow_description</item> - <item name="minWidth">@dimen/action_button_min_width_material</item> - <item name="minHeight">@dimen/action_button_min_height_material</item> <item name="paddingEnd">12dp</item> - <item name="scaleType">center</item> </style> <style name="Widget.Material.ActionBar.TabView" parent="Widget.ActionBar.TabView"> diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml index c578263..117e235 100644 --- a/core/res/res/values/symbols.xml +++ b/core/res/res/values/symbols.xml @@ -296,7 +296,7 @@ <java-symbol type="bool" name="config_windowEnableCircularEmulatorDisplayOverlay" /> <java-symbol type="bool" name="config_wifi_framework_enable_associated_autojoin_scan" /> <java-symbol type="bool" name="config_wifi_framework_enable_associated_network_selection" /> - + <java-symbol type="bool" name="config_wifi_only_link_same_credential_configurations" /> <java-symbol type="integer" name="config_bluetooth_max_advertisers" /> <java-symbol type="integer" name="config_bluetooth_max_scan_filters" /> <java-symbol type="integer" name="config_cursorWindowSize" /> @@ -1170,6 +1170,18 @@ <java-symbol type="drawable" name="sim_dark_orange" /> <java-symbol type="drawable" name="sim_dark_purple" /> + <java-symbol type="drawable" name="ic_account_circle" /> + <java-symbol type="color" name="user_icon_1" /> + <java-symbol type="color" name="user_icon_2" /> + <java-symbol type="color" name="user_icon_3" /> + <java-symbol type="color" name="user_icon_4" /> + <java-symbol type="color" name="user_icon_5" /> + <java-symbol type="color" name="user_icon_6" /> + <java-symbol type="color" name="user_icon_7" /> + <java-symbol type="color" name="user_icon_8" /> + <java-symbol type="color" name="user_icon_default_gray" /> + <java-symbol type="color" name="user_icon_default_white" /> + <java-symbol type="layout" name="action_bar_home" /> <java-symbol type="layout" name="action_bar_title_item" /> <java-symbol type="layout" name="action_menu_item_layout" /> diff --git a/core/res/res/values/themes.xml b/core/res/res/values/themes.xml index 48de5ad..d0097aa 100644 --- a/core/res/res/values/themes.xml +++ b/core/res/res/values/themes.xml @@ -192,6 +192,7 @@ please see themes_device_defaults.xml. <item name="navigationBarColor">@color/black</item> <item name="windowActionBarFullscreenDecorLayout">@layout/screen_action_bar</item> <item name="windowContentTransitions">false</item> + <item name="windowActivityTransitions">false</item> <!-- Define these here; ContextThemeWrappers around themes that define them should always clear these values. --> @@ -816,6 +817,7 @@ please see themes_device_defaults.xml. <!-- Theme for the dialog shown when an app crashes or ANRs. --> <style name="Theme.Dialog.AppError" parent="Theme.DeviceDefault.Light.Dialog.Alert"> <item name="windowContentTransitions">false</item> + <item name="windowActivityTransitions">false</item> <item name="windowCloseOnTouchOutside">false</item> </style> @@ -827,6 +829,7 @@ please see themes_device_defaults.xml. <item name="textColor">@color/secondary_text_nofocus</item> <item name="windowCloseOnTouchOutside">false</item> <item name="windowContentTransitions">false</item> + <item name="windowActivityTransitions">false</item> </style> <!-- Theme for a window that looks like a toast. --> @@ -836,6 +839,7 @@ please see themes_device_defaults.xml. <item name="backgroundDimEnabled">false</item> <item name="windowCloseOnTouchOutside">false</item> <item name="windowContentTransitions">false</item> + <item name="windowActivityTransitions">false</item> </style> </resources> diff --git a/core/res/res/values/themes_leanback.xml b/core/res/res/values/themes_leanback.xml index 720733f..82cf288 100644 --- a/core/res/res/values/themes_leanback.xml +++ b/core/res/res/values/themes_leanback.xml @@ -76,6 +76,7 @@ <style name="Theme.Leanback.Dialog.AppError" parent="Theme.Leanback.Dialog"> <item name="windowContentTransitions">false</item> + <item name="windowActivityTransitions">false</item> <item name="windowCloseOnTouchOutside">false</item> </style> diff --git a/core/res/res/values/themes_material.xml b/core/res/res/values/themes_material.xml index 485ea08..008e170 100644 --- a/core/res/res/values/themes_material.xml +++ b/core/res/res/values/themes_material.xml @@ -157,7 +157,8 @@ please see themes_device_defaults.xml. <item name="windowTitleStyle">@style/WindowTitle.Material</item> <item name="windowTitleSize">@dimen/action_bar_default_height_material</item> <item name="windowTitleBackgroundStyle">@style/WindowTitleBackground.Material</item> - <item name="windowContentTransitions">true</item> + <item name="windowContentTransitions">false</item> + <item name="windowActivityTransitions">true</item> <item name="windowAnimationStyle">@style/Animation.Material.Activity</item> <item name="windowSoftInputMode">stateUnspecified|adjustUnspecified</item> <item name="windowActionBar">true</item> @@ -511,7 +512,8 @@ please see themes_device_defaults.xml. <item name="windowEnterTransition">@transition/fade</item> <item name="windowSharedElementEnterTransition">@transition/move</item> <item name="windowSharedElementExitTransition">@transition/move</item> - <item name="windowContentTransitions">true</item> + <item name="windowContentTransitions">false</item> + <item name="windowActivityTransitions">true</item> <!-- Dialog attributes --> <item name="dialogTheme">@style/Theme.Material.Light.Dialog</item> diff --git a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/WifiAssociationTestRunner.java b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/WifiAssociationTestRunner.java index 2354484..f4ea6f2 100644 --- a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/WifiAssociationTestRunner.java +++ b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/WifiAssociationTestRunner.java @@ -16,17 +16,12 @@ package com.android.connectivitymanagertest; -import android.content.Context; -import android.net.wifi.WifiManager; -import android.os.Bundle; import android.test.InstrumentationTestRunner; import android.test.InstrumentationTestSuite; -import android.util.Log; import com.android.connectivitymanagertest.functional.WifiAssociationTest; import junit.framework.TestSuite; -import junit.framework.Assert; /** * Instrumentation Test Runner for wifi association test. @@ -39,8 +34,6 @@ import junit.framework.Assert; * -w com.android.connectivitymanagertest/.WifiAssociationTestRunner" */ public class WifiAssociationTestRunner extends InstrumentationTestRunner { - private static final String TAG = "WifiAssociationTestRunner"; - public int mBand; @Override public TestSuite getAllTests() { @@ -53,35 +46,4 @@ public class WifiAssociationTestRunner extends InstrumentationTestRunner { public ClassLoader getLoader() { return WifiAssociationTestRunner.class.getClassLoader(); } - - @Override - public void onCreate(Bundle icicle) { - super.onCreate(icicle); - String mFrequencyBand = icicle.getString("frequency-band"); - if (mFrequencyBand != null) { - setFrequencyBand(mFrequencyBand); - } - } - - private void setFrequencyBand(String band) { - WifiManager mWifiManager = (WifiManager)getContext().getSystemService(Context.WIFI_SERVICE); - if (band.equals("2.4")) { - Log.v(TAG, "set frequency band to 2.4"); - mBand = WifiManager.WIFI_FREQUENCY_BAND_2GHZ; - } else if (band.equals("5.0")) { - Log.v(TAG, "set frequency band to 5.0"); - mBand = WifiManager.WIFI_FREQUENCY_BAND_5GHZ; - } else if (band.equals("auto")) { - Log.v(TAG, "set frequency band to auto"); - mBand = WifiManager.WIFI_FREQUENCY_BAND_AUTO; - } else { - Assert.fail("invalid frequency band"); - } - int currentFreq = mWifiManager.getFrequencyBand(); - if (mBand == currentFreq) { - Log.v(TAG, "frequency band has been set"); - return; - } - mWifiManager.setFrequencyBand(mBand, true); - } } diff --git a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/functional/WifiAssociationTest.java b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/functional/WifiAssociationTest.java index c2b80dc..68f3179 100644 --- a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/functional/WifiAssociationTest.java +++ b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/functional/WifiAssociationTest.java @@ -16,14 +16,13 @@ package com.android.connectivitymanagertest.functional; -import android.net.ConnectivityManager; -import android.net.NetworkInfo.State; import android.net.wifi.WifiConfiguration; import android.net.wifi.WifiConfiguration.AuthAlgorithm; import android.net.wifi.WifiConfiguration.GroupCipher; import android.net.wifi.WifiConfiguration.PairwiseCipher; import android.net.wifi.WifiConfiguration.Protocol; import android.net.wifi.WifiInfo; +import android.net.wifi.WifiManager; import android.os.Bundle; import android.test.suitebuilder.annotation.LargeTest; @@ -39,13 +38,7 @@ import com.android.connectivitymanagertest.WifiConfigurationHelper; * -w com.android.connectivitymanagertest/.WifiAssociationTestRunner" */ public class WifiAssociationTest extends ConnectivityManagerTestBase { - private String mSsid = null; - private String mPassword = null; - private String mSecurityType = null; - private String mFrequencyBand = null; - private int mBand; - - enum SECURITY_TYPE { + private enum SecurityType { OPEN, WEP64, WEP128, WPA_TKIP, WPA2_AES } @@ -53,86 +46,106 @@ public class WifiAssociationTest extends ConnectivityManagerTestBase { super(WifiAssociationTest.class.getSimpleName()); } - @Override - protected void setUp() throws Exception { - super.setUp(); - WifiAssociationTestRunner runner = (WifiAssociationTestRunner)getInstrumentation(); + /** + * Test that the wifi can associate with a given access point. + */ + @LargeTest + public void testWifiAssociation() { + WifiAssociationTestRunner runner = (WifiAssociationTestRunner) getInstrumentation(); Bundle arguments = runner.getArguments(); - mSecurityType = arguments.getString("security-type"); - mSsid = arguments.getString("ssid"); - mPassword = arguments.getString("password"); - mFrequencyBand = arguments.getString("frequency-band"); - mBand = runner.mBand; - assertNotNull("security type is empty", mSecurityType); - assertNotNull("ssid is empty", mSsid); - validateFrequencyBand(); - - // enable wifi and verify wpa_supplicant is started + + String ssid = arguments.getString("ssid"); + assertNotNull("ssid is empty", ssid); + + String securityTypeStr = arguments.getString("security-type"); + assertNotNull("security-type is empty", securityTypeStr); + SecurityType securityType = SecurityType.valueOf(securityTypeStr); + + String password = arguments.getString("password"); + + String freqStr = arguments.getString("frequency-band"); + if (freqStr != null) { + setFrequencyBand(freqStr); + } + assertTrue("enable Wifi failed", enableWifi()); - assertTrue("wifi not connected", waitForNetworkState( - ConnectivityManager.TYPE_WIFI, State.CONNECTED, LONG_TIMEOUT)); WifiInfo wi = mWifiManager.getConnectionInfo(); + logv("%s", wi); assertNotNull("no active wifi info", wi); - assertTrue("failed to ping wpa_supplicant ", mWifiManager.pingSupplicant()); + + WifiConfiguration config = getConfig(ssid, securityType, password); + + logv("Network config: %s", config.toString()); + connectToWifi(config); } - private void validateFrequencyBand() { - if (mFrequencyBand != null) { - int currentFreq = mWifiManager.getFrequencyBand(); - logv("read frequency band: " + currentFreq); - assertEquals("specified frequency band does not match operational band of WifiManager", - currentFreq, mBand); - } + /** + * Set the frequency band and verify that it has been set. + */ + private void setFrequencyBand(String frequencyBandStr) { + int frequencyBand = -1; + if ("2.4".equals(frequencyBandStr)) { + frequencyBand = WifiManager.WIFI_FREQUENCY_BAND_2GHZ; + } else if ("5.0".equals(frequencyBandStr)) { + frequencyBand = WifiManager.WIFI_FREQUENCY_BAND_5GHZ; + } else if ("auto".equals(frequencyBandStr)) { + frequencyBand = WifiManager.WIFI_FREQUENCY_BAND_AUTO; + } else { + fail("Invalid frequency-band"); + } + if (mWifiManager.getFrequencyBand() != frequencyBand) { + logv("Set frequency band to %s", frequencyBandStr); + mWifiManager.setFrequencyBand(frequencyBand, true); + } + assertEquals("Specified frequency band does not match operational band", + frequencyBand, mWifiManager.getFrequencyBand()); } - @LargeTest - public void testWifiAssociation() { - assertNotNull("no test ssid", mSsid); + /** + * Get the {@link WifiConfiguration} based on ssid, security, and password. + */ + private WifiConfiguration getConfig(String ssid, SecurityType securityType, String password) { + logv("Security type is %s", securityType.toString()); + WifiConfiguration config = null; - SECURITY_TYPE security = SECURITY_TYPE.valueOf(mSecurityType); - logv("Security type is " + security.toString()); - switch (security) { - // set network configurations + switch (securityType) { case OPEN: - config = WifiConfigurationHelper.createOpenConfig(mSsid); + config = WifiConfigurationHelper.createOpenConfig(ssid); break; case WEP64: - assertNotNull("password is empty", mPassword); + assertNotNull("password is empty", password); // always use hex pair for WEP-40 - assertTrue(WifiConfigurationHelper.isHex(mPassword, 10)); - config = WifiConfigurationHelper.createWepConfig(mSsid, mPassword); + assertTrue(WifiConfigurationHelper.isHex(password, 10)); + config = WifiConfigurationHelper.createWepConfig(ssid, password); config.allowedGroupCiphers.set(GroupCipher.WEP40); break; case WEP128: - assertNotNull("password is empty", mPassword); + assertNotNull("password is empty", password); // always use hex pair for WEP-104 - assertTrue(WifiConfigurationHelper.isHex(mPassword, 26)); - config = WifiConfigurationHelper.createWepConfig(mSsid, mPassword); + assertTrue(WifiConfigurationHelper.isHex(password, 26)); + config = WifiConfigurationHelper.createWepConfig(ssid, password); config.allowedGroupCiphers.set(GroupCipher.WEP104); break; case WPA_TKIP: - assertNotNull("password is empty", mPassword); - config = WifiConfigurationHelper.createPskConfig(mSsid, mPassword); + assertNotNull("password is empty", password); + config = WifiConfigurationHelper.createPskConfig(ssid, password); config.allowedAuthAlgorithms.set(AuthAlgorithm.OPEN); config.allowedProtocols.set(Protocol.WPA); config.allowedPairwiseCiphers.set(PairwiseCipher.TKIP); config.allowedGroupCiphers.set(GroupCipher.TKIP); break; case WPA2_AES: - assertNotNull("password is empty", mPassword); - config = WifiConfigurationHelper.createPskConfig(mSsid, mPassword); + assertNotNull("password is empty", password); + config = WifiConfigurationHelper.createPskConfig(ssid, password); config.allowedAuthAlgorithms.set(AuthAlgorithm.OPEN); config.allowedProtocols.set(Protocol.RSN); config.allowedPairwiseCiphers.set(PairwiseCipher.CCMP); config.allowedGroupCiphers.set(GroupCipher.CCMP); break; default: - fail("Not a valid security type: " + mSecurityType); + fail("Not a valid security type: " + securityType); break; } - logv("network config: %s", config.toString()); - connectToWifi(config); - // verify that connection actually works - assertTrue("no network connectivity at end of test", checkNetworkConnectivity()); + return config; } } diff --git a/core/tests/inputmethodtests/src/android/os/InputMethodTest.java b/core/tests/inputmethodtests/src/android/os/InputMethodTest.java index 30eb939..cb85fc5 100644 --- a/core/tests/inputmethodtests/src/android/os/InputMethodTest.java +++ b/core/tests/inputmethodtests/src/android/os/InputMethodTest.java @@ -45,177 +45,99 @@ public class InputMethodTest extends InstrumentationTestCase { private static final Locale LOCALE_EN_GB = new Locale("en", "GB"); private static final Locale LOCALE_EN_IN = new Locale("en", "IN"); private static final Locale LOCALE_HI = new Locale("hi"); + private static final Locale LOCALE_JA_JP = new Locale("ja", "JP"); + private static final String SUBTYPE_MODE_KEYBOARD = "keyboard"; + private static final String SUBTYPE_MODE_VOICE = "voice"; @SmallTest - public void testDefaultEnabledImesWithDefaultVoiceIme() throws Exception { - final Context context = getInstrumentation().getTargetContext(); - final ArrayList<InputMethodInfo> imis = new ArrayList<InputMethodInfo>(); - imis.add(createDefaultAutoDummyVoiceIme()); - imis.add(createNonDefaultAutoDummyVoiceIme0()); - imis.add(createNonDefaultAutoDummyVoiceIme1()); - imis.add(createNonDefaultDummyVoiceIme2()); - imis.add(createDefaultDummyLatinKeyboardIme()); - imis.add(createNonDefaultDummyJaJPKeyboardIme()); - imis.add(createNonDefaultDummyJaJPKeyboardImeWithoutSubtypes()); - imis.add(createDefaultDummyHinglishKeyboardIme()); - - // locale: en_US, system: not ready - final ArrayList<InputMethodInfo> enabledImisForSystemNotReadyLocaleEnUs = - callGetDefaultEnabledImesUnderWithLocale(context, !IS_SYSTEM_READY, imis, - LOCALE_EN_US); - assertEquals(toSet("DummyDefaultAutoVoiceIme", "DummyDefaultEnKeyboardIme", + public void testVoiceImes() throws Exception { + // locale: en_US + assertDefaultEnabledImes(getImesWithDefaultVoiceIme(), LOCALE_EN_US, !IS_SYSTEM_READY, "DummyNonDefaultAutoVoiceIme0", "DummyNonDefaultAutoVoiceIme1", - "DummyDefaultHinglishKeyboardIme"), - getPackageNames(enabledImisForSystemNotReadyLocaleEnUs)); - - // locale: en_US, system: ready - final ArrayList<InputMethodInfo> enabledImisForSystemReadyLocaleEnUs = - callGetDefaultEnabledImesUnderWithLocale(context, IS_SYSTEM_READY, imis, - LOCALE_EN_US); - assertEquals(toSet("DummyDefaultAutoVoiceIme", "DummyDefaultEnKeyboardIme", - "DummyDefaultHinglishKeyboardIme"), - getPackageNames(enabledImisForSystemReadyLocaleEnUs)); - - // locale: en_GB, system: not ready - final ArrayList<InputMethodInfo> enabledImisForSystemNotReadyLocaleEnGB = - callGetDefaultEnabledImesUnderWithLocale(context, !IS_SYSTEM_READY, imis, - LOCALE_EN_GB); - assertEquals(toSet("DummyDefaultAutoVoiceIme", "DummyDefaultEnKeyboardIme", + "DummyDefaultEnKeyboardIme", "DummyDefaultAutoVoiceIme"); + assertDefaultEnabledImes(getImesWithoutDefaultVoiceIme(), LOCALE_EN_US, !IS_SYSTEM_READY, "DummyNonDefaultAutoVoiceIme0", "DummyNonDefaultAutoVoiceIme1", - "DummyDefaultHinglishKeyboardIme"), - getPackageNames(enabledImisForSystemNotReadyLocaleEnGB)); - - // locale: en_GB, system: ready - final ArrayList<InputMethodInfo> enabledImisForSystemReadyLocaleEnGB = - callGetDefaultEnabledImesUnderWithLocale(context, IS_SYSTEM_READY, imis, - LOCALE_EN_GB); - assertEquals(toSet("DummyDefaultAutoVoiceIme", "DummyDefaultEnKeyboardIme", - "DummyDefaultHinglishKeyboardIme"), - getPackageNames(enabledImisForSystemReadyLocaleEnGB)); - - // locale: en_IN, system: not ready - final ArrayList<InputMethodInfo> enabledImisForSystemNotReadyLocaleEnIN = - callGetDefaultEnabledImesUnderWithLocale(context, !IS_SYSTEM_READY, imis, - LOCALE_EN_IN); - assertEquals(toSet("DummyDefaultAutoVoiceIme", "DummyDefaultEnKeyboardIme", + "DummyDefaultEnKeyboardIme"); + assertDefaultEnabledImes(getImesWithDefaultVoiceIme(), LOCALE_EN_US, IS_SYSTEM_READY, + "DummyDefaultAutoVoiceIme", "DummyDefaultEnKeyboardIme"); + assertDefaultEnabledImes(getImesWithoutDefaultVoiceIme(), LOCALE_EN_US, IS_SYSTEM_READY, "DummyNonDefaultAutoVoiceIme0", "DummyNonDefaultAutoVoiceIme1", - "DummyDefaultHinglishKeyboardIme"), - getPackageNames(enabledImisForSystemNotReadyLocaleEnIN)); + "DummyDefaultEnKeyboardIme"); - // locale: en_IN, system: ready - final ArrayList<InputMethodInfo> enabledImisForSystemReadyLocaleEnIN = - callGetDefaultEnabledImesUnderWithLocale(context, IS_SYSTEM_READY, imis, - LOCALE_EN_IN); - assertEquals(toSet("DummyDefaultAutoVoiceIme", "DummyDefaultEnKeyboardIme", - "DummyDefaultHinglishKeyboardIme"), - getPackageNames(enabledImisForSystemReadyLocaleEnIN)); - - // locale: hi, system: not ready - final ArrayList<InputMethodInfo> enabledImisForSystemNotReadyLocaleHi = - callGetDefaultEnabledImesUnderWithLocale(context, !IS_SYSTEM_READY, imis, - LOCALE_HI); - assertEquals(toSet("DummyDefaultAutoVoiceIme", "DummyDefaultEnKeyboardIme", + // locale: en_GB + assertDefaultEnabledImes(getImesWithDefaultVoiceIme(), LOCALE_EN_GB, !IS_SYSTEM_READY, + "DummyNonDefaultAutoVoiceIme0", "DummyNonDefaultAutoVoiceIme1", + "DummyDefaultEnKeyboardIme", "DummyDefaultAutoVoiceIme"); + assertDefaultEnabledImes(getImesWithoutDefaultVoiceIme(), LOCALE_EN_GB, !IS_SYSTEM_READY, + "DummyNonDefaultAutoVoiceIme0", "DummyNonDefaultAutoVoiceIme1", + "DummyDefaultEnKeyboardIme"); + assertDefaultEnabledImes(getImesWithDefaultVoiceIme(), LOCALE_EN_GB, IS_SYSTEM_READY, + "DummyDefaultEnKeyboardIme", "DummyDefaultAutoVoiceIme"); + assertDefaultEnabledImes(getImesWithoutDefaultVoiceIme(), LOCALE_EN_GB, IS_SYSTEM_READY, "DummyNonDefaultAutoVoiceIme0", "DummyNonDefaultAutoVoiceIme1", - "DummyDefaultHinglishKeyboardIme"), - getPackageNames(enabledImisForSystemNotReadyLocaleHi)); + "DummyDefaultEnKeyboardIme"); - // locale: hi, system: ready - final ArrayList<InputMethodInfo> enabledImisForSystemReadyLocaleHi = - callGetDefaultEnabledImesUnderWithLocale(context, IS_SYSTEM_READY, imis, - LOCALE_HI); - assertEquals(toSet("DummyDefaultAutoVoiceIme", "DummyDefaultEnKeyboardIme", + // locale: ja_JP + assertDefaultEnabledImes(getImesWithDefaultVoiceIme(), LOCALE_JA_JP, !IS_SYSTEM_READY, + "DummyNonDefaultAutoVoiceIme0", "DummyNonDefaultAutoVoiceIme1", + "DummyDefaultEnKeyboardIme", "DummyDefaultAutoVoiceIme"); + assertDefaultEnabledImes(getImesWithoutDefaultVoiceIme(), LOCALE_JA_JP, !IS_SYSTEM_READY, + "DummyNonDefaultAutoVoiceIme0", "DummyNonDefaultAutoVoiceIme1", + "DummyDefaultEnKeyboardIme"); + assertDefaultEnabledImes(getImesWithDefaultVoiceIme(), LOCALE_JA_JP, IS_SYSTEM_READY, "DummyNonDefaultAutoVoiceIme0", "DummyNonDefaultAutoVoiceIme1", - "DummyDefaultHinglishKeyboardIme"), - getPackageNames(enabledImisForSystemReadyLocaleHi)); + "DummyDefaultEnKeyboardIme", "DummyDefaultAutoVoiceIme"); + assertDefaultEnabledImes(getImesWithoutDefaultVoiceIme(), LOCALE_JA_JP, IS_SYSTEM_READY, + "DummyNonDefaultAutoVoiceIme0", "DummyNonDefaultAutoVoiceIme1", + "DummyDefaultEnKeyboardIme"); } @SmallTest - public void testDefaultEnabledImesWithOutDefaultVoiceIme() throws Exception { - final Context context = getInstrumentation().getTargetContext(); - final ArrayList<InputMethodInfo> imis = new ArrayList<InputMethodInfo>(); - imis.add(createNonDefaultAutoDummyVoiceIme0()); - imis.add(createNonDefaultAutoDummyVoiceIme1()); - imis.add(createNonDefaultDummyVoiceIme2()); - imis.add(createDefaultDummyLatinKeyboardIme()); - imis.add(createNonDefaultDummyJaJPKeyboardIme()); - imis.add(createNonDefaultDummyJaJPKeyboardImeWithoutSubtypes()); - imis.add(createDefaultDummyHinglishKeyboardIme()); - - // locale: en_US, system: not ready - final ArrayList<InputMethodInfo> enabledImisForSystemNotReadyLocaleEnUs = - callGetDefaultEnabledImesUnderWithLocale(context, !IS_SYSTEM_READY, imis, - LOCALE_EN_US); - assertEquals(toSet("DummyNonDefaultAutoVoiceIme0", "DummyNonDefaultAutoVoiceIme1", - "DummyDefaultEnKeyboardIme", "DummyDefaultHinglishKeyboardIme"), - getPackageNames(enabledImisForSystemNotReadyLocaleEnUs)); - - // locale: en_US, system: ready - final ArrayList<InputMethodInfo> enabledImisForSystemReadyLocaleEnUs = - callGetDefaultEnabledImesUnderWithLocale(context, IS_SYSTEM_READY, imis, - LOCALE_EN_US); - assertEquals(toSet("DummyNonDefaultAutoVoiceIme0", "DummyNonDefaultAutoVoiceIme1", - "DummyDefaultEnKeyboardIme", "DummyDefaultHinglishKeyboardIme"), - getPackageNames(enabledImisForSystemReadyLocaleEnUs)); - - // locale: en_GB, system: not ready - final ArrayList<InputMethodInfo> enabledImisForSystemNotReadyLocaleEnGB = - callGetDefaultEnabledImesUnderWithLocale(context, !IS_SYSTEM_READY, imis, - LOCALE_EN_GB); - assertEquals(toSet("DummyNonDefaultAutoVoiceIme0", "DummyNonDefaultAutoVoiceIme1", - "DummyDefaultEnKeyboardIme", "DummyDefaultHinglishKeyboardIme"), - getPackageNames(enabledImisForSystemNotReadyLocaleEnGB)); - - // locale: en_GB, system: ready - final ArrayList<InputMethodInfo> enabledImisForSystemReadyLocaleEnGB = - callGetDefaultEnabledImesUnderWithLocale(context, IS_SYSTEM_READY, imis, - LOCALE_EN_GB); - assertEquals(toSet("DummyNonDefaultAutoVoiceIme0", "DummyNonDefaultAutoVoiceIme1", - "DummyDefaultEnKeyboardIme", "DummyDefaultHinglishKeyboardIme"), - getPackageNames(enabledImisForSystemReadyLocaleEnGB)); - - // locale: en_IN, system: not ready - final ArrayList<InputMethodInfo> enabledImisForSystemNotReadyLocaleEnIN = - callGetDefaultEnabledImesUnderWithLocale(context, !IS_SYSTEM_READY, imis, - LOCALE_EN_IN); - assertEquals(toSet("DummyNonDefaultAutoVoiceIme0", "DummyNonDefaultAutoVoiceIme1", - "DummyDefaultEnKeyboardIme", "DummyDefaultHinglishKeyboardIme"), - getPackageNames(enabledImisForSystemNotReadyLocaleEnIN)); - - // locale: en_IN, system: ready - final ArrayList<InputMethodInfo> enabledImisForSystemReadyLocaleEnIN = - callGetDefaultEnabledImesUnderWithLocale(context, IS_SYSTEM_READY, imis, - LOCALE_EN_IN); - assertEquals(toSet("DummyNonDefaultAutoVoiceIme0", "DummyNonDefaultAutoVoiceIme1", - "DummyDefaultEnKeyboardIme", "DummyDefaultHinglishKeyboardIme"), - getPackageNames(enabledImisForSystemReadyLocaleEnIN)); - - // locale: hi, system: not ready - final ArrayList<InputMethodInfo> enabledImisForSystemNotReadyLocaleHi = - callGetDefaultEnabledImesUnderWithLocale(context, !IS_SYSTEM_READY, imis, - LOCALE_HI); - assertEquals(toSet("DummyNonDefaultAutoVoiceIme0", "DummyNonDefaultAutoVoiceIme1", - "DummyDefaultEnKeyboardIme", "DummyDefaultHinglishKeyboardIme"), - getPackageNames(enabledImisForSystemNotReadyLocaleHi)); - - // locale: hi, system: ready - final ArrayList<InputMethodInfo> enabledImisForSystemReadyLocaleHi = - callGetDefaultEnabledImesUnderWithLocale(context, IS_SYSTEM_READY, imis, - LOCALE_HI); - assertEquals(toSet("DummyNonDefaultAutoVoiceIme0", "DummyNonDefaultAutoVoiceIme1", - "DummyDefaultEnKeyboardIme", "DummyDefaultHinglishKeyboardIme"), - getPackageNames(enabledImisForSystemReadyLocaleHi)); + public void testKeyboardImes() throws Exception { + // locale: en_US + assertDefaultEnabledImes(getSamplePreinstalledImes(), LOCALE_EN_US, !IS_SYSTEM_READY, + "com.android.apps.inputmethod.voice", "com.android.apps.inputmethod.latin", + "com.android.apps.inputmethod.hindi"); + assertDefaultEnabledImes(getSamplePreinstalledImes(), LOCALE_EN_US, IS_SYSTEM_READY, + "com.android.apps.inputmethod.voice", "com.android.apps.inputmethod.latin", + "com.android.apps.inputmethod.hindi"); + + // locale: en_GB + assertDefaultEnabledImes(getSamplePreinstalledImes(), LOCALE_EN_GB, !IS_SYSTEM_READY, + "com.android.apps.inputmethod.voice", "com.android.apps.inputmethod.latin", + "com.android.apps.inputmethod.hindi"); + assertDefaultEnabledImes(getSamplePreinstalledImes(), LOCALE_EN_GB, IS_SYSTEM_READY, + "com.android.apps.inputmethod.voice", "com.android.apps.inputmethod.latin", + "com.android.apps.inputmethod.hindi"); + + // locale: en_IN + assertDefaultEnabledImes(getSamplePreinstalledImes(), LOCALE_EN_IN, !IS_SYSTEM_READY, + "com.android.apps.inputmethod.voice", "com.android.apps.inputmethod.latin", + "com.android.apps.inputmethod.hindi"); + assertDefaultEnabledImes(getSamplePreinstalledImes(), LOCALE_EN_IN, IS_SYSTEM_READY, + "com.android.apps.inputmethod.voice", "com.android.apps.inputmethod.latin", + "com.android.apps.inputmethod.hindi"); + + // locale: hi + assertDefaultEnabledImes(getSamplePreinstalledImes(), LOCALE_HI, !IS_SYSTEM_READY, + "com.android.apps.inputmethod.voice", "com.android.apps.inputmethod.latin", + "com.android.apps.inputmethod.hindi"); + assertDefaultEnabledImes(getSamplePreinstalledImes(), LOCALE_HI, IS_SYSTEM_READY, + "com.android.apps.inputmethod.voice", "com.android.apps.inputmethod.latin", + "com.android.apps.inputmethod.hindi"); + + // locale: ja_JP + assertDefaultEnabledImes(getSamplePreinstalledImes(), LOCALE_JA_JP, !IS_SYSTEM_READY, + "com.android.apps.inputmethod.voice", "com.android.apps.inputmethod.latin", + "com.android.apps.inputmethod.hindi"); + assertDefaultEnabledImes(getSamplePreinstalledImes(), LOCALE_JA_JP, IS_SYSTEM_READY, + "com.android.apps.inputmethod.voice", "com.android.apps.inputmethod.latin", + "com.android.apps.inputmethod.hindi", "com.android.apps.inputmethod.japanese"); } @SmallTest public void testParcelable() throws Exception { - final ArrayList<InputMethodInfo> originalList = new ArrayList<InputMethodInfo>(); - originalList.add(createNonDefaultAutoDummyVoiceIme0()); - originalList.add(createNonDefaultAutoDummyVoiceIme1()); - originalList.add(createNonDefaultDummyVoiceIme2()); - originalList.add(createDefaultDummyLatinKeyboardIme()); - originalList.add(createNonDefaultDummyJaJPKeyboardIme()); - originalList.add(createNonDefaultDummyJaJPKeyboardImeWithoutSubtypes()); - + final ArrayList<InputMethodInfo> originalList = getSamplePreinstalledImes(); final List<InputMethodInfo> clonedList = cloneViaParcel(originalList); assertNotNull(clonedList); final List<InputMethodInfo> clonedClonedList = cloneViaParcel(clonedList); @@ -230,6 +152,14 @@ public class InputMethodTest extends InstrumentationTestCase { } } + private void assertDefaultEnabledImes(final ArrayList<InputMethodInfo> preinstalledImes, + final Locale systemLocale, final boolean isSystemReady, String... imeNames) { + final Context context = getInstrumentation().getTargetContext(); + assertEquals(new HashSet<String>(Arrays.asList(imeNames)), + getPackageNames(callGetDefaultEnabledImesUnderWithLocale(context, + isSystemReady, preinstalledImes, systemLocale))); + } + private static List<InputMethodInfo> cloneViaParcel(final List<InputMethodInfo> list) { Parcel p = null; try { @@ -256,11 +186,6 @@ public class InputMethodTest extends InstrumentationTestCase { } } - @SafeVarargs - private static <T> HashSet<T> toSet(final T... xs) { - return new HashSet<T>(Arrays.asList(xs)); - } - private HashSet<String> getPackageNames(final ArrayList<InputMethodInfo> imis) { final HashSet<String> packageNames = new HashSet<>(); for (final InputMethodInfo imi : imis) { @@ -315,83 +240,132 @@ public class InputMethodTest extends InstrumentationTestCase { .build(); } - private static InputMethodInfo createDefaultAutoDummyVoiceIme() { - final ArrayList<InputMethodSubtype> subtypes = new ArrayList<InputMethodSubtype>(); - subtypes.add(createDummyInputMethodSubtype("auto", "voice", IS_AUX, IS_AUTO, - !IS_ASCII_CAPABLE)); - subtypes.add(createDummyInputMethodSubtype("en_US", "voice", IS_AUX, !IS_AUTO, - !IS_ASCII_CAPABLE)); - return createDummyInputMethodInfo("DummyDefaultAutoVoiceIme", "dummy.voice0", - "DummyVoice0", IS_AUX, IS_DEFAULT, subtypes); + private static ArrayList<InputMethodInfo> getImesWithDefaultVoiceIme() { + ArrayList<InputMethodInfo> preinstalledImes = new ArrayList<>(); + { + final ArrayList<InputMethodSubtype> subtypes = new ArrayList<InputMethodSubtype>(); + subtypes.add(createDummyInputMethodSubtype("auto", SUBTYPE_MODE_VOICE, IS_AUX, IS_AUTO, + !IS_ASCII_CAPABLE)); + subtypes.add(createDummyInputMethodSubtype("en_US", SUBTYPE_MODE_VOICE, IS_AUX, + !IS_AUTO, !IS_ASCII_CAPABLE)); + preinstalledImes.add(createDummyInputMethodInfo("DummyDefaultAutoVoiceIme", + "dummy.voice0", "DummyVoice0", IS_AUX, IS_DEFAULT, subtypes)); + } + preinstalledImes.addAll(getImesWithoutDefaultVoiceIme()); + return preinstalledImes; } - private static InputMethodInfo createNonDefaultAutoDummyVoiceIme0() { - final ArrayList<InputMethodSubtype> subtypes = new ArrayList<InputMethodSubtype>(); - subtypes.add(createDummyInputMethodSubtype("auto", "voice", IS_AUX, IS_AUTO, - !IS_ASCII_CAPABLE)); - subtypes.add(createDummyInputMethodSubtype("en_US", "voice", IS_AUX, !IS_AUTO, - !IS_ASCII_CAPABLE)); - return createDummyInputMethodInfo("DummyNonDefaultAutoVoiceIme0", "dummy.voice1", - "DummyVoice1", IS_AUX, !IS_DEFAULT, subtypes); + private static ArrayList<InputMethodInfo> getImesWithoutDefaultVoiceIme() { + ArrayList<InputMethodInfo> preinstalledImes = new ArrayList<>(); + { + final ArrayList<InputMethodSubtype> subtypes = new ArrayList<InputMethodSubtype>(); + subtypes.add(createDummyInputMethodSubtype("auto", SUBTYPE_MODE_VOICE, IS_AUX, IS_AUTO, + !IS_ASCII_CAPABLE)); + subtypes.add(createDummyInputMethodSubtype("en_US", SUBTYPE_MODE_VOICE, IS_AUX, + !IS_AUTO, !IS_ASCII_CAPABLE)); + preinstalledImes.add(createDummyInputMethodInfo("DummyNonDefaultAutoVoiceIme0", + "dummy.voice1", "DummyVoice1", IS_AUX, !IS_DEFAULT, subtypes)); + } + { + final ArrayList<InputMethodSubtype> subtypes = new ArrayList<InputMethodSubtype>(); + subtypes.add(createDummyInputMethodSubtype("auto", SUBTYPE_MODE_VOICE, IS_AUX, IS_AUTO, + !IS_ASCII_CAPABLE)); + subtypes.add(createDummyInputMethodSubtype("en_US", SUBTYPE_MODE_VOICE, IS_AUX, + !IS_AUTO, !IS_ASCII_CAPABLE)); + preinstalledImes.add(createDummyInputMethodInfo("DummyNonDefaultAutoVoiceIme1", + "dummy.voice2", "DummyVoice2", IS_AUX, !IS_DEFAULT, subtypes)); + } + { + final ArrayList<InputMethodSubtype> subtypes = new ArrayList<InputMethodSubtype>(); + subtypes.add(createDummyInputMethodSubtype("en_US", SUBTYPE_MODE_VOICE, IS_AUX, + !IS_AUTO, !IS_ASCII_CAPABLE)); + preinstalledImes.add(createDummyInputMethodInfo("DummyNonDefaultVoiceIme2", + "dummy.voice3", "DummyVoice3", IS_AUX, !IS_DEFAULT, subtypes)); + } + { + final ArrayList<InputMethodSubtype> subtypes = new ArrayList<InputMethodSubtype>(); + subtypes.add(createDummyInputMethodSubtype("en_US", SUBTYPE_MODE_KEYBOARD, !IS_AUX, + !IS_AUTO, IS_ASCII_CAPABLE)); + preinstalledImes.add(createDummyInputMethodInfo("DummyDefaultEnKeyboardIme", + "dummy.keyboard0", "DummyKeyboard0", !IS_AUX, IS_DEFAULT, subtypes)); + } + return preinstalledImes; } - private static InputMethodInfo createNonDefaultAutoDummyVoiceIme1() { - final ArrayList<InputMethodSubtype> subtypes = new ArrayList<InputMethodSubtype>(); - subtypes.add(createDummyInputMethodSubtype("auto", "voice", IS_AUX, IS_AUTO, - !IS_ASCII_CAPABLE)); - subtypes.add(createDummyInputMethodSubtype("en_US", "voice", IS_AUX, !IS_AUTO, - !IS_ASCII_CAPABLE)); - return createDummyInputMethodInfo("DummyNonDefaultAutoVoiceIme1", "dummy.voice2", - "DummyVoice2", IS_AUX, !IS_DEFAULT, subtypes); - } + private static ArrayList<InputMethodInfo> getSamplePreinstalledImes() { + ArrayList<InputMethodInfo> preinstalledImes = new ArrayList<>(); + + // a dummy Voice IME + { + final ArrayList<InputMethodSubtype> subtypes = new ArrayList<InputMethodSubtype>(); + subtypes.add(createDummyInputMethodSubtype("", SUBTYPE_MODE_VOICE, IS_AUX, + IS_AUTO, !IS_ASCII_CAPABLE)); + preinstalledImes.add(createDummyInputMethodInfo("com.android.apps.inputmethod.voice", + "com.android.inputmethod.voice", "DummyVoiceIme", IS_AUX, IS_DEFAULT, + subtypes)); + } - private static InputMethodInfo createNonDefaultDummyVoiceIme2() { - final ArrayList<InputMethodSubtype> subtypes = new ArrayList<InputMethodSubtype>(); - subtypes.add(createDummyInputMethodSubtype("en_US", "voice", IS_AUX, !IS_AUTO, - !IS_ASCII_CAPABLE)); - return createDummyInputMethodInfo("DummyNonDefaultVoiceIme2", "dummy.voice3", - "DummyVoice3", IS_AUX, !IS_DEFAULT, subtypes); - } + // a dummy Hindi IME + { + final ArrayList<InputMethodSubtype> subtypes = new ArrayList<InputMethodSubtype>(); + // TODO: This subtype should be marked as IS_ASCII_CAPABLE + subtypes.add(createDummyInputMethodSubtype("en_IN", SUBTYPE_MODE_KEYBOARD, !IS_AUX, + !IS_AUTO, !IS_ASCII_CAPABLE)); + subtypes.add(createDummyInputMethodSubtype("hi", SUBTYPE_MODE_KEYBOARD, !IS_AUX, + !IS_AUTO, !IS_ASCII_CAPABLE)); + preinstalledImes.add(createDummyInputMethodInfo("com.android.apps.inputmethod.hindi", + "com.android.inputmethod.hindi", "DummyHindiIme", !IS_AUX, IS_DEFAULT, + subtypes)); + } - private static InputMethodInfo createDefaultDummyLatinKeyboardIme() { - final ArrayList<InputMethodSubtype> subtypes = new ArrayList<InputMethodSubtype>(); - subtypes.add(createDummyInputMethodSubtype("en_US", "keyboard", !IS_AUX, !IS_AUTO, - IS_ASCII_CAPABLE)); - subtypes.add(createDummyInputMethodSubtype("en_GB", "keyboard", !IS_AUX, !IS_AUTO, - IS_ASCII_CAPABLE)); - subtypes.add(createDummyInputMethodSubtype("en_IN", "keyboard", !IS_AUX, !IS_AUTO, - IS_ASCII_CAPABLE)); - subtypes.add(createDummyInputMethodSubtype("hi", "keyboard", !IS_AUX, !IS_AUTO, - !IS_ASCII_CAPABLE)); // not AsciiCapable! - subtypes.add(createDummyInputMethodSubtype("hi_ZZ", "keyboard", !IS_AUX, !IS_AUTO, - IS_ASCII_CAPABLE)); - return createDummyInputMethodInfo("DummyDefaultEnKeyboardIme", "dummy.keyboard0", - "DummyKeyboard0", !IS_AUX, IS_DEFAULT, subtypes); - } + // a dummy Pinyin IME + { + final ArrayList<InputMethodSubtype> subtypes = new ArrayList<InputMethodSubtype>(); + subtypes.add(createDummyInputMethodSubtype("zh_CN", SUBTYPE_MODE_KEYBOARD, !IS_AUX, + !IS_AUTO, !IS_ASCII_CAPABLE)); + preinstalledImes.add(createDummyInputMethodInfo("ccom.android.apps.inputmethod.pinyin", + "com.android.apps.inputmethod.pinyin", "DummyPinyinIme", !IS_AUX, IS_DEFAULT, + subtypes)); + } - private static InputMethodInfo createNonDefaultDummyJaJPKeyboardIme() { - final ArrayList<InputMethodSubtype> subtypes = new ArrayList<InputMethodSubtype>(); - subtypes.add(createDummyInputMethodSubtype("ja_JP", "keyboard", !IS_AUX, !IS_AUTO, - IS_ASCII_CAPABLE)); - return createDummyInputMethodInfo("DummyNonDefaultJaJPKeyboardIme", "dummy.keyboard1", - "DummyKeyboard1", !IS_AUX, !IS_DEFAULT, subtypes); - } + // a dummy Korian IME + { + final ArrayList<InputMethodSubtype> subtypes = new ArrayList<InputMethodSubtype>(); + subtypes.add(createDummyInputMethodSubtype("ko", SUBTYPE_MODE_KEYBOARD, !IS_AUX, + !IS_AUTO, !IS_ASCII_CAPABLE)); + preinstalledImes.add(createDummyInputMethodInfo("com.android.apps.inputmethod.korean", + "com.android.apps.inputmethod.korean", "DummyKorianIme", !IS_AUX, IS_DEFAULT, + subtypes)); + } - // Although IMEs that have no subtype are considered to be deprecated, the Android framework - // must still be able to handle such IMEs as well as IMEs that have at least one subtype. - private static InputMethodInfo createNonDefaultDummyJaJPKeyboardImeWithoutSubtypes() { - final ArrayList<InputMethodSubtype> subtypes = new ArrayList<InputMethodSubtype>(); - return createDummyInputMethodInfo("DummyNonDefaultJaJPKeyboardImeWithoutSubtypes", - "dummy.keyboard2", "DummyKeyboard2", !IS_AUX, !IS_DEFAULT, NO_SUBTYPE); - } + // a dummy Latin IME + { + final ArrayList<InputMethodSubtype> subtypes = new ArrayList<InputMethodSubtype>(); + subtypes.add(createDummyInputMethodSubtype("en_US", SUBTYPE_MODE_KEYBOARD, !IS_AUX, + !IS_AUTO, IS_ASCII_CAPABLE)); + subtypes.add(createDummyInputMethodSubtype("en_GB", SUBTYPE_MODE_KEYBOARD, !IS_AUX, + !IS_AUTO, IS_ASCII_CAPABLE)); + subtypes.add(createDummyInputMethodSubtype("en_IN", SUBTYPE_MODE_KEYBOARD, !IS_AUX, + !IS_AUTO, IS_ASCII_CAPABLE)); + subtypes.add(createDummyInputMethodSubtype("hi", SUBTYPE_MODE_KEYBOARD, !IS_AUX, + !IS_AUTO, IS_ASCII_CAPABLE)); + preinstalledImes.add(createDummyInputMethodInfo("com.android.apps.inputmethod.latin", + "com.android.apps.inputmethod.latin", "DummyLatinIme", !IS_AUX, IS_DEFAULT, + subtypes)); + } + + // a dummy Japanese IME + { + final ArrayList<InputMethodSubtype> subtypes = new ArrayList<InputMethodSubtype>(); + subtypes.add(createDummyInputMethodSubtype("ja", SUBTYPE_MODE_KEYBOARD, !IS_AUX, + !IS_AUTO, !IS_ASCII_CAPABLE)); + subtypes.add(createDummyInputMethodSubtype("emoji", SUBTYPE_MODE_KEYBOARD, !IS_AUX, + !IS_AUTO, !IS_ASCII_CAPABLE)); + preinstalledImes.add(createDummyInputMethodInfo("com.android.apps.inputmethod.japanese", + "com.android.apps.inputmethod.japanese", "DummyJapaneseIme", !IS_AUX, + IS_DEFAULT, subtypes)); + } - private static InputMethodInfo createDefaultDummyHinglishKeyboardIme() { - final ArrayList<InputMethodSubtype> subtypes = new ArrayList<InputMethodSubtype>(); - subtypes.add(createDummyInputMethodSubtype("en_IN", "keyboard", !IS_AUX, !IS_AUTO, - IS_ASCII_CAPABLE)); - subtypes.add(createDummyInputMethodSubtype("hi", "keyboard", !IS_AUX, !IS_AUTO, - !IS_ASCII_CAPABLE)); // not AsciiCapable! - return createDummyInputMethodInfo("DummyDefaultHinglishKeyboardIme", "dummy.keyboard2", - "DummyKeyboard2", !IS_AUX, IS_DEFAULT, subtypes); + return preinstalledImes; } } diff --git a/graphics/java/android/graphics/Canvas.java b/graphics/java/android/graphics/Canvas.java index 0927ffd..f45c0cb 100644 --- a/graphics/java/android/graphics/Canvas.java +++ b/graphics/java/android/graphics/Canvas.java @@ -250,11 +250,6 @@ public class Canvas { public void insertInorderBarrier() {} /** - * @hide - */ - public void initializeLight(float lightX, float lightY, float lightZ, float lightRadius) {} - - /** * Return true if the device that the current layer draws into is opaque * (i.e. does not support per-pixel alpha). * @@ -416,10 +411,10 @@ public class Canvas { * @return value to pass to restoreToCount() to balance this save() */ public int saveLayer(@Nullable RectF bounds, @Nullable Paint paint, @Saveflags int saveFlags) { - return native_saveLayer(mNativeCanvasWrapper, - bounds.left, bounds.top, bounds.right, bounds.bottom, - paint != null ? paint.mNativePaint : 0, - saveFlags); + if (bounds == null) { + bounds = new RectF(getClipBounds()); + } + return saveLayer(bounds.left, bounds.top, bounds.right, bounds.bottom, paint, saveFlags); } /** @@ -462,17 +457,17 @@ public class Canvas { * @param saveFlags see _SAVE_FLAG constants * @return value to pass to restoreToCount() to balance this call */ - public int saveLayerAlpha(@NonNull RectF bounds, int alpha, @Saveflags int saveFlags) { - alpha = Math.min(255, Math.max(0, alpha)); - return native_saveLayerAlpha(mNativeCanvasWrapper, - bounds.left, bounds.top, bounds.right, bounds.bottom, - alpha, saveFlags); + public int saveLayerAlpha(@Nullable RectF bounds, int alpha, @Saveflags int saveFlags) { + if (bounds == null) { + bounds = new RectF(getClipBounds()); + } + return saveLayerAlpha(bounds.left, bounds.top, bounds.right, bounds.bottom, alpha, saveFlags); } /** * Convenience for saveLayerAlpha(bounds, alpha, {@link #ALL_SAVE_FLAG}) */ - public int saveLayerAlpha(@NonNull RectF bounds, int alpha) { + public int saveLayerAlpha(@Nullable RectF bounds, int alpha) { return saveLayerAlpha(bounds, alpha, ALL_SAVE_FLAG); } @@ -481,6 +476,7 @@ public class Canvas { */ public int saveLayerAlpha(float left, float top, float right, float bottom, int alpha, @Saveflags int saveFlags) { + alpha = Math.min(255, Math.max(0, alpha)); return native_saveLayerAlpha(mNativeCanvasWrapper, left, top, right, bottom, alpha, saveFlags); } diff --git a/graphics/java/android/graphics/drawable/GradientDrawable.java b/graphics/java/android/graphics/drawable/GradientDrawable.java index e1c88cb..2916d6c 100644 --- a/graphics/java/android/graphics/drawable/GradientDrawable.java +++ b/graphics/java/android/graphics/drawable/GradientDrawable.java @@ -1638,6 +1638,11 @@ public class GradientDrawable extends Drawable { } } + // An unfilled shape is not opaque over bounds or shape + if (mColors == null && mColorStateList == null) { + return; + } + // Colors are opaque, so opaqueOverShape=true, mOpaqueOverShape = true; // and opaqueOverBounds=true if shape fills bounds diff --git a/include/android_runtime/AndroidRuntime.h b/include/android_runtime/AndroidRuntime.h index 51e47e6..f3cfd97 100644 --- a/include/android_runtime/AndroidRuntime.h +++ b/include/android_runtime/AndroidRuntime.h @@ -45,6 +45,7 @@ public: }; void setArgv0(const char* argv0); + void addOption(const char* optionString, void* extra_info = NULL); /** * Register a set of methods in the specified class. @@ -63,8 +64,6 @@ public: */ static jclass findClass(JNIEnv* env, const char* className); - int addVmArguments(int argc, const char* const argv[]); - void start(const char *classname, const Vector<String8>& options); void exit(int code); @@ -116,7 +115,6 @@ public: private: static int startReg(JNIEnv* env); - void addOption(const char* optionString, void* extra_info = NULL); bool parseRuntimeOption(const char* property, char* buffer, const char* runtimeArg, diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp index dbd273d..0415efa 100755 --- a/libs/hwui/OpenGLRenderer.cpp +++ b/libs/hwui/OpenGLRenderer.cpp @@ -54,10 +54,6 @@ namespace android { namespace uirenderer { -/////////////////////////////////////////////////////////////////////////////// -// Defines -/////////////////////////////////////////////////////////////////////////////// - static GLenum getFilter(const SkPaint* paint) { if (!paint || paint->getFilterLevel() != SkPaint::kNone_FilterLevel) { return GL_LINEAR; @@ -1748,10 +1744,13 @@ void OpenGLRenderer::setupDrawProgram() { glUniform4f(mCaches.currentProgram->getUniform("roundRectInnerRectLTRB"), innerRect.left, innerRect.top, innerRect.right, innerRect.bottom); - glUniform1f(mCaches.currentProgram->getUniform("roundRectRadius"), - state->radius); glUniformMatrix4fv(mCaches.currentProgram->getUniform("roundRectInvTransform"), 1, GL_FALSE, &state->matrix.data[0]); + + // add half pixel to round out integer rect space to cover pixel centers + float roundedOutRadius = state->radius + 0.5f; + glUniform1f(mCaches.currentProgram->getUniform("roundRectRadius"), + roundedOutRadius); } } @@ -3044,21 +3043,35 @@ void OpenGLRenderer::resetPaintFilter() { } void OpenGLRenderer::setupPaintFilter(int clearBits, int setBits) { + // TODO: don't bother with boolean, it's redundant with clear/set bits mDrawModifiers.mHasDrawFilter = true; mDrawModifiers.mPaintFilterClearBits = clearBits & SkPaint::kAllFlags; mDrawModifiers.mPaintFilterSetBits = setBits & SkPaint::kAllFlags; } const SkPaint* OpenGLRenderer::filterPaint(const SkPaint* paint) { + // TODO: use CompatFlagsDrawFilter here, and combine logic with android/graphics/DrawFilter.cpp + // to avoid clobbering 0x02 paint flag + + // Equivalent to the Java Paint's FILTER_BITMAP_FLAG. + static const uint32_t sFilterBitmapFlag = 0x02; + if (CC_LIKELY(!mDrawModifiers.mHasDrawFilter || !paint)) { return paint; } - uint32_t flags = paint->getFlags(); + const uint32_t clearBits = mDrawModifiers.mPaintFilterClearBits; + const uint32_t setBits = mDrawModifiers.mPaintFilterSetBits; + const uint32_t flags = (paint->getFlags() & ~clearBits) | setBits; mFilteredPaint = *paint; - mFilteredPaint.setFlags((flags & ~mDrawModifiers.mPaintFilterClearBits) | - mDrawModifiers.mPaintFilterSetBits); + mFilteredPaint.setFlags(flags); + + // check if paint filter trying to override bitmap filter + if ((clearBits | setBits) & sFilterBitmapFlag) { + mFilteredPaint.setFilterLevel(flags & sFilterBitmapFlag + ? SkPaint::kLow_FilterLevel : SkPaint::kNone_FilterLevel); + } return &mFilteredPaint; } diff --git a/libs/hwui/TessellationCache.cpp b/libs/hwui/TessellationCache.cpp index 9e62f36..1e38f9e 100644 --- a/libs/hwui/TessellationCache.cpp +++ b/libs/hwui/TessellationCache.cpp @@ -216,7 +216,7 @@ static void tessellateShadows( // tessellate caster outline into a 2d polygon Vector<Vertex> casterVertices2d; - const float casterRefinementThresholdSquared = 20.0f; // TODO: experiment with this value + const float casterRefinementThresholdSquared = 4.0f; PathTessellator::approximatePathOutlineVertices(*casterPerimeter, casterRefinementThresholdSquared, casterVertices2d); if (!ShadowTessellator::isClockwisePath(*casterPerimeter)) { diff --git a/packages/PrintSpooler/res/layout/print_activity_controls.xml b/packages/PrintSpooler/res/layout/print_activity_controls.xml index c2a0da9..f0b8adf 100644 --- a/packages/PrintSpooler/res/layout/print_activity_controls.xml +++ b/packages/PrintSpooler/res/layout/print_activity_controls.xml @@ -55,7 +55,7 @@ android:text="@string/label_copies"> </TextView> - <EditText + <com.android.printspooler.widget.CustomErrorEditText android:id="@+id/copies_edittext" android:layout_width="fill_parent" android:layout_height="wrap_content" @@ -63,7 +63,7 @@ android:singleLine="true" android:ellipsize="end" android:inputType="numberDecimal"> - </EditText> + </com.android.printspooler.widget.CustomErrorEditText> </LinearLayout> @@ -197,7 +197,7 @@ android:visibility="visible"> </TextView> - <EditText + <com.android.printspooler.widget.CustomErrorEditText android:id="@+id/page_range_edittext" android:layout_width="fill_parent" android:layout_height="wrap_content" @@ -206,7 +206,7 @@ android:ellipsize="end" android:visibility="visible" android:inputType="textNoSuggestions"> - </EditText> + </com.android.printspooler.widget.CustomErrorEditText> </LinearLayout> diff --git a/packages/PrintSpooler/src/com/android/printspooler/model/PrintSpoolerProvider.java b/packages/PrintSpooler/src/com/android/printspooler/model/PrintSpoolerProvider.java index 06723c3..8537d6c 100644 --- a/packages/PrintSpooler/src/com/android/printspooler/model/PrintSpoolerProvider.java +++ b/packages/PrintSpooler/src/com/android/printspooler/model/PrintSpoolerProvider.java @@ -20,7 +20,9 @@ import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.ServiceConnection; +import android.os.Debug; import android.os.IBinder; +import android.util.Log; public class PrintSpoolerProvider implements ServiceConnection { private final Context mContext; diff --git a/packages/PrintSpooler/src/com/android/printspooler/model/RemotePrintDocument.java b/packages/PrintSpooler/src/com/android/printspooler/model/RemotePrintDocument.java index 1e7a011..239f006 100644 --- a/packages/PrintSpooler/src/com/android/printspooler/model/RemotePrintDocument.java +++ b/packages/PrintSpooler/src/com/android/printspooler/model/RemotePrintDocument.java @@ -74,7 +74,7 @@ public final class RemotePrintDocument { private final Looper mLooper; private final IPrintDocumentAdapter mPrintDocumentAdapter; - private final DocumentObserver mDocumentObserver; + private final RemoteAdapterDeathObserver mAdapterDeathObserver; private final UpdateResultCallbacks mUpdateCallbacks; @@ -135,7 +135,7 @@ public final class RemotePrintDocument { private final DeathRecipient mDeathRecipient = new DeathRecipient() { @Override public void binderDied() { - finish(); + mAdapterDeathObserver.onDied(); } }; @@ -144,8 +144,8 @@ public final class RemotePrintDocument { private AsyncCommand mCurrentCommand; private AsyncCommand mNextCommand; - public interface DocumentObserver { - public void onDestroy(); + public interface RemoteAdapterDeathObserver { + public void onDied(); } public interface UpdateResultCallbacks { @@ -155,12 +155,12 @@ public final class RemotePrintDocument { } public RemotePrintDocument(Context context, IPrintDocumentAdapter adapter, - MutexFileProvider fileProvider, DocumentObserver destroyListener, + MutexFileProvider fileProvider, RemoteAdapterDeathObserver deathObserver, UpdateResultCallbacks callbacks) { mPrintDocumentAdapter = adapter; mLooper = context.getMainLooper(); mContext = context; - mDocumentObserver = destroyListener; + mAdapterDeathObserver = deathObserver; mDocumentInfo = new RemotePrintDocumentInfo(); mDocumentInfo.fileProvider = fileProvider; mUpdateCallbacks = callbacks; @@ -180,7 +180,7 @@ public final class RemotePrintDocument { } catch (RemoteException re) { Log.e(LOG_TAG, "Error calling start()", re); mState = STATE_FAILED; - mDocumentObserver.onDestroy(); + mAdapterDeathObserver.onDied(); } } @@ -269,7 +269,7 @@ public final class RemotePrintDocument { } catch (RemoteException re) { Log.e(LOG_TAG, "Error calling finish()", re); mState = STATE_FAILED; - mDocumentObserver.onDestroy(); + mAdapterDeathObserver.onDied(); } } @@ -302,7 +302,6 @@ public final class RemotePrintDocument { mState = STATE_DESTROYED; disconnectFromRemoteDocument(); - mDocumentObserver.onDestroy(); } public boolean isUpdating() { @@ -1124,7 +1123,7 @@ public final class RemotePrintDocument { new Handler(document.mLooper).post(new Runnable() { @Override public void run() { - document.mDocumentObserver.onDestroy(); + document.mAdapterDeathObserver.onDied(); } }); } diff --git a/packages/PrintSpooler/src/com/android/printspooler/ui/PrintActivity.java b/packages/PrintSpooler/src/com/android/printspooler/ui/PrintActivity.java index 967efd4..dc2d5b1 100644 --- a/packages/PrintSpooler/src/com/android/printspooler/ui/PrintActivity.java +++ b/packages/PrintSpooler/src/com/android/printspooler/ui/PrintActivity.java @@ -284,11 +284,14 @@ public class PrintActivity extends Activity implements RemotePrintDocument.Updat mFileProvider); mPrintedDocument = new RemotePrintDocument(PrintActivity.this, IPrintDocumentAdapter.Stub.asInterface(documentAdapter), - mFileProvider, new RemotePrintDocument.DocumentObserver() { + mFileProvider, new RemotePrintDocument.RemoteAdapterDeathObserver() { @Override - public void onDestroy() { + public void onDied() { + if (isFinishing()) { + return; + } setState(STATE_PRINT_CANCELED); - finish(); + doFinish(); } }, PrintActivity.this); mProgressMessageController = new ProgressMessageController( @@ -342,17 +345,6 @@ public class PrintActivity extends Activity implements RemotePrintDocument.Updat spooler.setPrintJobState(mPrintJob.getId(), PrintJobInfo.STATE_CANCELED, null); } break; } - - mProgressMessageController.cancel(); - mPrinterRegistry.setTrackedPrinter(null); - mPrintPreviewController.destroy(); - mSpoolerProvider.destroy(); - - if (mPrintedDocument.isUpdating()) { - mPrintedDocument.cancel(); - } - mPrintedDocument.finish(); - mPrintedDocument.destroy(); } mPrinterAvailabilityDetector.cancel(); @@ -372,7 +364,12 @@ public class PrintActivity extends Activity implements RemotePrintDocument.Updat @Override public boolean onKeyUp(int keyCode, KeyEvent event) { if (mState == STATE_INITIALIZING) { - finish(); + doFinish(); + return true; + } + + if (mState == STATE_PRINT_CANCELED ||mState == STATE_PRINT_CONFIRMED + || mState == STATE_PRINT_COMPLETED) { return true; } @@ -430,7 +427,7 @@ public class PrintActivity extends Activity implements RemotePrintDocument.Updat } break; case STATE_PRINT_CANCELED: { - finish(); + doFinish(); } break; } } @@ -467,7 +464,7 @@ public class PrintActivity extends Activity implements RemotePrintDocument.Updat } break; case STATE_PRINT_CANCELED: { - finish(); + doFinish(); } break; default: { @@ -600,7 +597,7 @@ public class PrintActivity extends Activity implements RemotePrintDocument.Updat mDestinationSpinner.post(new Runnable() { @Override public void run() { - finish(); + doFinish(); } }); } @@ -962,7 +959,7 @@ public class PrintActivity extends Activity implements RemotePrintDocument.Updat if (mPrintedDocument.isUpdating()) { mPrintedDocument.cancel(); } - finish(); + doFinish(); } private void confirmPrint() { @@ -1539,11 +1536,23 @@ public class PrintActivity extends Activity implements RemotePrintDocument.Updat if (writeToUri != null) { mPrintedDocument.writeContent(getContentResolver(), writeToUri); } - finish(); + doFinish(); } }).shred(); } + private void doFinish() { + if (mState != STATE_INITIALIZING) { + mProgressMessageController.cancel(); + mPrinterRegistry.setTrackedPrinter(null); + mPrintPreviewController.destroy(); + mSpoolerProvider.destroy(); + mPrintedDocument.finish(); + mPrintedDocument.destroy(); + } + finish(); + } + private final class SpinnerItem<T> { final T value; final CharSequence label; diff --git a/packages/PrintSpooler/src/com/android/printspooler/ui/PrinterRegistry.java b/packages/PrintSpooler/src/com/android/printspooler/ui/PrinterRegistry.java index a3d7f01..7f48217 100644 --- a/packages/PrintSpooler/src/com/android/printspooler/ui/PrinterRegistry.java +++ b/packages/PrintSpooler/src/com/android/printspooler/ui/PrinterRegistry.java @@ -26,6 +26,7 @@ import android.os.Message; import android.print.PrinterId; import android.print.PrinterInfo; import com.android.internal.os.SomeArgs; +import com.android.printspooler.model.PrintSpoolerService; import java.util.ArrayList; import java.util.List; @@ -68,23 +69,40 @@ public class PrinterRegistry { } public void addHistoricalPrinter(PrinterInfo printer) { - getPrinterProvider().addHistoricalPrinter(printer); + FusedPrintersProvider provider = getPrinterProvider(); + if (provider != null) { + getPrinterProvider().addHistoricalPrinter(printer); + } } public void forgetFavoritePrinter(PrinterId printerId) { - getPrinterProvider().forgetFavoritePrinter(printerId); + FusedPrintersProvider provider = getPrinterProvider(); + if (provider != null) { + provider.forgetFavoritePrinter(printerId); + } } public boolean isFavoritePrinter(PrinterId printerId) { - return getPrinterProvider().isFavoritePrinter(printerId); + FusedPrintersProvider provider = getPrinterProvider(); + if (provider != null) { + return provider.isFavoritePrinter(printerId); + } + return false; } public void setTrackedPrinter(PrinterId printerId) { - getPrinterProvider().setTrackedPrinter(printerId); + FusedPrintersProvider provider = getPrinterProvider(); + if (provider != null) { + provider.setTrackedPrinter(printerId); + } } public boolean areHistoricalPrintersLoaded() { - return getPrinterProvider().areHistoricalPrintersLoaded(); + FusedPrintersProvider provider = getPrinterProvider(); + if (provider != null) { + return getPrinterProvider().areHistoricalPrintersLoaded(); + } + return false; } private FusedPrintersProvider getPrinterProvider() { diff --git a/packages/PrintSpooler/src/com/android/printspooler/widget/CustomErrorEditText.java b/packages/PrintSpooler/src/com/android/printspooler/widget/CustomErrorEditText.java new file mode 100644 index 0000000..b2aa008 --- /dev/null +++ b/packages/PrintSpooler/src/com/android/printspooler/widget/CustomErrorEditText.java @@ -0,0 +1,44 @@ +/* + * 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.printspooler.widget; + +import android.content.Context; +import android.graphics.drawable.Drawable; +import android.util.AttributeSet; +import android.widget.EditText; + +/** + * EditText that shows an error without a popup. + */ +public final class CustomErrorEditText extends EditText { + private CharSequence mError; + + public CustomErrorEditText(Context context, AttributeSet attrs) { + super(context, attrs); + } + + @Override + public CharSequence getError() { + return mError; + } + + @Override + public void setError(CharSequence error, Drawable icon) { + setCompoundDrawables(null, null, icon, null); + mError = error; + } +}
\ No newline at end of file diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java index 4ef2189..30ccd2c 100644 --- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java +++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java @@ -789,8 +789,15 @@ public class SettingsProvider extends ContentProvider { Slog.v(TAG, "putting to additional user " + mManagedProfiles.get(i).id); } - insertForUser(Settings.Secure.CONTENT_URI, values, - mManagedProfiles.get(i).id); + try { + insertForUser(Settings.Secure.CONTENT_URI, values, + mManagedProfiles.get(i).id); + } catch (SecurityException e) { + // Temporary fix, see b/17450158 + Slog.w(TAG, "Cannot clone request '" + request + "' with value '" + + newValue + "' to managed profile (id " + + mManagedProfiles.get(i).id + ")", e); + } } } finally { Binder.restoreCallingIdentity(token); diff --git a/packages/SystemUI/res/drawable/ic_account_circle_qs.xml b/packages/SystemUI/res/drawable/ic_account_circle_qs.xml deleted file mode 100644 index d10a96d..0000000 --- a/packages/SystemUI/res/drawable/ic_account_circle_qs.xml +++ /dev/null @@ -1,34 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> - -<!-- - ~ Copyright (C) 2014 The Android Open Source Project - ~ - ~ Licensed under the Apache License, Version 2.0 (the "License"); - ~ you may not use this file except in compliance with the License. - ~ You may obtain a copy of the License at - ~ - ~ http://www.apache.org/licenses/LICENSE-2.0 - ~ - ~ Unless required by applicable law or agreed to in writing, software - ~ distributed under the License is distributed on an "AS IS" BASIS, - ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - ~ See the License for the specific language governing permissions and - ~ limitations under the License - --> - -<vector xmlns:android="http://schemas.android.com/apk/res/android" - android:width="24dp" - android:height="24dp" - android:viewportWidth="24.0" - android:viewportHeight="24.0"> - - <group - android:scaleX="1.2" - android:scaleY="1.2" - android:pivotX="12.0" - android:pivotY="12.0"> - <path - android:fillColor="@color/qs_user_detail_icon_muted" - android:pathData="M12.0,2.0C6.5,2.0 2.0,6.5 2.0,12.0s4.5,10.0 10.0,10.0c5.5,0.0 10.0,-4.5 10.0,-10.0S17.5,2.0 12.0,2.0zM12.0,5.0c1.7,0.0 3.0,1.3 3.0,3.0c0.0,1.7 -1.3,3.0 -3.0,3.0c-1.7,0.0 -3.0,-1.3 -3.0,-3.0C9.0,6.3 10.3,5.0 12.0,5.0zM12.0,19.2c-2.5,0.0 -4.7,-1.3 -6.0,-3.2c0.0,-2.0 4.0,-3.1 6.0,-3.1c2.0,0.0 6.0,1.1 6.0,3.1C16.7,17.9 14.5,19.2 12.0,19.2z"/> - </group> -</vector> diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java index f7e0c83..ce3739c 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java @@ -92,6 +92,7 @@ import com.android.systemui.SwipeHelper; import com.android.systemui.SystemUI; import com.android.systemui.statusbar.NotificationData.Entry; import com.android.systemui.statusbar.phone.KeyguardTouchDelegate; +import com.android.systemui.statusbar.phone.PhoneStatusBar; import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager; import com.android.systemui.statusbar.policy.HeadsUpNotificationView; import com.android.systemui.statusbar.policy.PreviewInflater; @@ -288,6 +289,10 @@ public abstract class BaseStatusBar extends SystemUI implements // close the shade if it was open if (handled) { + if (PhoneStatusBar.DEBUG_EMPTY_KEYGUARD) { + Log.i(TAG, "Collapsing panel from mOnClickHandler after keyguard" + + "dismiss"); + } animateCollapsePanels(CommandQueue.FLAG_EXCLUDE_NONE, true /* force */); visibilityChanged(false); } @@ -334,6 +339,9 @@ public abstract class BaseStatusBar extends SystemUI implements Settings.Secure.putInt(mContext.getContentResolver(), Settings.Secure.SHOW_NOTE_ABOUT_NOTIFICATION_HIDING, 0); if (BANNER_ACTION_SETUP.equals(action)) { + if (PhoneStatusBar.DEBUG_EMPTY_KEYGUARD) { + Log.i(TAG, "Animating collapse because of BANNER_ACTION_SETUP"); + } animateCollapsePanels(CommandQueue.FLAG_EXCLUDE_NONE, true /* force */); mContext.startActivity(new Intent(Settings.ACTION_APP_NOTIFICATION_REDACTION) .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) @@ -759,6 +767,10 @@ public abstract class BaseStatusBar extends SystemUI implements } } }); + if (PhoneStatusBar.DEBUG_EMPTY_KEYGUARD) { + Log.i(TAG, "Collapsing panel from startNotificationGutsIntent after keyguard" + + "dismiss"); + } animateCollapsePanels(CommandQueue.FLAG_EXCLUDE_NONE, true /* force */); return true; } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java index e84ca52..20eed3f 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java @@ -128,6 +128,9 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL public boolean performAccessibilityAction(View host, int action, Bundle args) { if (action == ACTION_CLICK) { if (host == mLockIcon) { + if (PhoneStatusBar.DEBUG_EMPTY_KEYGUARD) { + Log.i(TAG, "Collapsing panel from lock icon accessibility click"); + } mPhoneStatusBar.animateCollapsePanels( CommandQueue.FLAG_EXCLUDE_NONE, true /* force */); return true; @@ -373,7 +376,8 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL return; } // TODO: Real icon for facelock. - int iconRes = mUnlockMethodCache.isFaceUnlockRunning() ? R.drawable.ic_account_circle + int iconRes = mUnlockMethodCache.isFaceUnlockRunning() + ? com.android.internal.R.drawable.ic_account_circle : mUnlockMethodCache.isMethodInsecure() ? R.drawable.ic_lock_open_24dp : R.drawable.ic_lock_24dp; mLockIcon.setImageResource(iconRes); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelBar.java index f74d2f4..ccafbd1 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelBar.java @@ -140,6 +140,9 @@ public class PanelBar extends FrameLayout { mPanelHolder.setSelectedPanel(mTouchingPanel); for (PanelView pv : mPanels) { if (pv != panel) { + if (PhoneStatusBar.DEBUG_EMPTY_KEYGUARD) { + Log.i(TAG, "Collapsing because opening another panel"); + } pv.collapse(false /* delayed */); } } @@ -191,9 +194,15 @@ public class PanelBar extends FrameLayout { boolean waiting = false; for (PanelView pv : mPanels) { if (animate && !pv.isFullyCollapsed()) { + if (PhoneStatusBar.DEBUG_EMPTY_KEYGUARD) { + Log.i(TAG, "Animating collapse, delayed"); + } pv.collapse(true /* delayed */); waiting = true; } else { + if (PhoneStatusBar.DEBUG_EMPTY_KEYGUARD) { + Log.i(TAG, "Collapsing without animation"); + } pv.resetViews(); pv.setExpandedFraction(0); // just in case pv.setVisibility(View.GONE); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java index 006e480..c3b263d 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java @@ -134,6 +134,9 @@ public abstract class PanelView extends FrameLayout { } private void runPeekAnimation() { + if (PhoneStatusBar.DEBUG_EMPTY_KEYGUARD) { + Log.i(TAG, "Starting peek animation"); + } mPeekHeight = getPeekHeight(); if (DEBUG) logf("peek to height=%.1f", mPeekHeight); if (mHeightAnimator != null) { @@ -154,9 +157,15 @@ public abstract class PanelView extends FrameLayout { public void onAnimationEnd(Animator animation) { mPeekAnimator = null; if (mCollapseAfterPeek && !mCancelled) { + if (PhoneStatusBar.DEBUG_EMPTY_KEYGUARD) { + Log.i(TAG, "Peek animation finished, posting collapse"); + } postOnAnimation(new Runnable() { @Override public void run() { + if (PhoneStatusBar.DEBUG_EMPTY_KEYGUARD) { + Log.i(TAG, "Peek animation finished, collapsing"); + } collapse(false /* delayed */); } }); @@ -330,6 +339,9 @@ public abstract class PanelView extends FrameLayout { } boolean expand = flingExpands(vel, vectorVel); onTrackingStopped(expand); + if (PhoneStatusBar.DEBUG_EMPTY_KEYGUARD) { + Log.i(TAG, "Flinging: expand=" + expand); + } fling(vel, expand); mUpdateFlingOnLayout = expand && mPanelClosedOnDown && !mHasLayoutedSinceDown; if (mUpdateFlingOnLayout) { @@ -510,6 +522,9 @@ public abstract class PanelView extends FrameLayout { notifyExpandingFinished(); return; } + if (PhoneStatusBar.DEBUG_EMPTY_KEYGUARD) { + Log.i(TAG, "Executing fling: expand=" + expand + " vel=" + vel); + } mOverExpandedBeforeFling = getOverExpansionAmount() > 0f; ValueAnimator animator = createHeightAnimator(target); if (expand) { @@ -691,8 +706,14 @@ public abstract class PanelView extends FrameLayout { mClosing = true; notifyExpandingStarted(); if (delayed) { + if (PhoneStatusBar.DEBUG_EMPTY_KEYGUARD) { + Log.i(TAG, "Posting collapse runnable, will be run in 120ms"); + } postDelayed(mFlingCollapseRunnable, 120); } else { + if (PhoneStatusBar.DEBUG_EMPTY_KEYGUARD) { + Log.i(TAG, "Animating collapsing now"); + } fling(0, false /* expand */); } } @@ -701,6 +722,9 @@ public abstract class PanelView extends FrameLayout { private final Runnable mFlingCollapseRunnable = new Runnable() { @Override public void run() { + if (PhoneStatusBar.DEBUG_EMPTY_KEYGUARD) { + Log.i(TAG, "Executing collapse runnable, animating collapsing now"); + } fling(0, false /* expand */); } }; @@ -729,6 +753,11 @@ public abstract class PanelView extends FrameLayout { } public void instantExpand() { + if (PhoneStatusBar.DEBUG_EMPTY_KEYGUARD) { + Log.i(TAG, "Before instant expanding" + + " mTracking=" + mTracking + + " mExpanding=" + mExpanding); + } mInstantExpanding = true; mUpdateFlingOnLayout = false; abortAnimations(); @@ -749,6 +778,11 @@ public abstract class PanelView extends FrameLayout { public void onGlobalLayout() { if (mStatusBar.getStatusBarWindow().getHeight() != mStatusBar.getStatusBarHeight()) { + if (PhoneStatusBar.DEBUG_EMPTY_KEYGUARD) { + Log.i(TAG, "Now instant expanding after layout" + + " mTracking=" + mTracking + + " mExpanding=" + mExpanding); + } getViewTreeObserver().removeOnGlobalLayoutListener(this); setExpandedFraction(1f); mInstantExpanding = false; @@ -895,6 +929,9 @@ public abstract class PanelView extends FrameLayout { private final Runnable mPostCollapseRunnable = new Runnable() { @Override public void run() { + if (PhoneStatusBar.DEBUG_EMPTY_KEYGUARD) { + Log.i(TAG, "Collapsing after middle clicked"); + } collapse(false /* delayed */); } }; @@ -907,6 +944,9 @@ public abstract class PanelView extends FrameLayout { mStatusBar.goToKeyguard(); return true; case StatusBarState.SHADE: + if (PhoneStatusBar.DEBUG_EMPTY_KEYGUARD) { + Log.i(TAG, "Middle clicked in shade state, posting collapsing runnable"); + } // This gets called in the middle of the touch handling, where the state is still // that we are tracking the panel. Collapse the panel after this is done. diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java index 271383f..fd60ac4 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java @@ -177,6 +177,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, public static final boolean DEBUG_GESTURES = false; public static final boolean DEBUG_MEDIA = false; public static final boolean DEBUG_MEDIA_FAKE_ARTWORK = false; + public static final boolean DEBUG_EMPTY_KEYGUARD = true; public static final boolean DEBUG_WINDOW_STATE = false; @@ -2238,6 +2239,11 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, mStatusBarWindowManager.setStatusBarFocusable(false); mStatusBarWindow.cancelExpandHelper(); + if (DEBUG_EMPTY_KEYGUARD) { + Log.i(TAG, "Collapsing panel from animateCollapsePanels:" + + " force=" + force + + " mState=" + mState); + } mStatusBarView.collapseAllPanels(true); } } @@ -2325,6 +2331,9 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, } public void animateCollapseQuickSettings() { + if (DEBUG_EMPTY_KEYGUARD) { + Log.i(TAG, "Collapsing panel from animateCollapseQuickSettings"); + } mStatusBarView.collapseAllPanels(true); } @@ -2337,6 +2346,9 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, } // Ensure the panel is fully collapsed (just in case; bug 6765842, 7260868) + if (DEBUG_EMPTY_KEYGUARD) { + Log.i(TAG, "Collapsing panel from makeExpandedInvisible"); + } mStatusBarView.collapseAllPanels(/*animate=*/ false); // reset things to their proper state @@ -2430,6 +2442,9 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, mStatusBarWindowState = state; if (DEBUG_WINDOW_STATE) Log.d(TAG, "Status bar " + windowStateToString(state)); if (!showing) { + if (DEBUG_EMPTY_KEYGUARD) { + Log.i(TAG, "Collapsing panel from setWindowState"); + } mStatusBarView.collapseAllPanels(false); } } @@ -2987,6 +3002,10 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, } }); if (dismissShade) { + if (PhoneStatusBar.DEBUG_EMPTY_KEYGUARD) { + Log.i(TAG, "Collapsing panel startActivityDismissKeyguard after keyguard" + + "dismiss"); + } animateCollapsePanels(CommandQueue.FLAG_EXCLUDE_NONE, true /* force */); } return true; @@ -3654,6 +3673,9 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, public boolean onSpacePressed() { if (mScreenOn != null && mScreenOn && (mState == StatusBarState.KEYGUARD || mState == StatusBarState.SHADE_LOCKED)) { + if (PhoneStatusBar.DEBUG_EMPTY_KEYGUARD) { + Log.i(TAG, "Collapsing panel from onSpacePressed"); + } animateCollapsePanels(0 /* flags */, true /* force */); return true; } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserInfoController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserInfoController.java index 8cbe272..d50e39f 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserInfoController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserInfoController.java @@ -17,7 +17,6 @@ package com.android.systemui.statusbar.policy; import android.app.ActivityManagerNative; -import android.bluetooth.BluetoothAdapter; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; @@ -26,33 +25,21 @@ import android.content.pm.PackageManager; import android.content.pm.UserInfo; import android.database.Cursor; import android.graphics.Bitmap; -import android.graphics.BitmapShader; -import android.graphics.Canvas; -import android.graphics.Matrix; -import android.graphics.Paint; -import android.graphics.PorterDuff; -import android.graphics.PorterDuffXfermode; -import android.graphics.Rect; -import android.graphics.RectF; -import android.graphics.Shader; import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.Drawable; -import android.hardware.display.DisplayManager; import android.os.AsyncTask; import android.os.RemoteException; import android.os.UserHandle; import android.os.UserManager; import android.provider.ContactsContract; -import android.security.KeyChain; import android.util.Log; import android.util.Pair; -import com.android.internal.view.RotationPolicy; import com.android.systemui.BitmapHelper; import com.android.systemui.R; +import com.android.internal.util.UserIcons; import java.util.ArrayList; -import java.util.concurrent.CopyOnWriteArrayList; public final class UserInfoController { @@ -142,6 +129,7 @@ public final class UserInfoController { throw new RuntimeException(e); } final int userId = userInfo.id; + final boolean isGuest = userInfo.isGuest(); final String userName = userInfo.name; final int avatarSize = mContext.getResources().getDimensionPixelSize(R.dimen.max_avatar_size); @@ -161,7 +149,8 @@ public final class UserInfoController { avatar = new BitmapDrawable(mContext.getResources(), BitmapHelper.createCircularClip(rawAvatar, avatarSize, avatarSize)); } else { - avatar = mContext.getResources().getDrawable(R.drawable.ic_account_circle); + avatar = UserIcons.getDefaultUserIcon(isGuest? UserHandle.USER_NULL : userId, + /* light= */ true); mUseDefaultAvatar = true; } 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 d02826f..e8f35fd 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java @@ -16,13 +16,6 @@ package com.android.systemui.statusbar.policy; -import com.android.systemui.BitmapHelper; -import com.android.systemui.GuestResumeSessionReceiver; -import com.android.systemui.R; -import com.android.systemui.qs.QSTile; -import com.android.systemui.qs.tiles.UserDetailView; -import com.android.systemui.statusbar.phone.SystemUIDialog; - import android.app.ActivityManager; import android.app.ActivityManagerNative; import android.app.Dialog; @@ -45,9 +38,16 @@ import android.util.Log; import android.util.SparseArray; import android.view.View; import android.view.ViewGroup; -import android.view.WindowManagerGlobal; import android.widget.BaseAdapter; +import com.android.internal.util.UserIcons; +import com.android.systemui.BitmapHelper; +import com.android.systemui.GuestResumeSessionReceiver; +import com.android.systemui.R; +import com.android.systemui.qs.QSTile; +import com.android.systemui.qs.tiles.UserDetailView; +import com.android.systemui.statusbar.phone.SystemUIDialog; + import java.io.FileDescriptor; import java.io.PrintWriter; import java.lang.ref.WeakReference; @@ -425,7 +425,8 @@ public class UserSwitcherController { if (item.isAddUser) { return context.getDrawable(R.drawable.ic_add_circle_qs); } - return context.getDrawable(R.drawable.ic_account_circle_qs); + return UserIcons.getDefaultUserIcon(item.isGuest ? UserHandle.USER_NULL : item.info.id, + /* light= */ true); } } @@ -565,6 +566,9 @@ public class UserSwitcherController { dismiss(); int id = mUserManager.createUser( mContext.getString(R.string.user_new_user_name), 0 /* flags */).id; + Bitmap icon = UserIcons.convertToBitmap(UserIcons.getDefaultUserIcon( + id, /* light= */ false)); + mUserManager.setUserIcon(id, icon); switchToUserId(id); } } diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindow.java b/policy/src/com/android/internal/policy/impl/PhoneWindow.java index cce30c7..92171c1 100644 --- a/policy/src/com/android/internal/policy/impl/PhoneWindow.java +++ b/policy/src/com/android/internal/policy/impl/PhoneWindow.java @@ -124,6 +124,7 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback { private static final int CUSTOM_TITLE_COMPATIBLE_FEATURES = DEFAULT_FEATURES | (1 << FEATURE_CUSTOM_TITLE) | (1 << FEATURE_CONTENT_TRANSITIONS) | + (1 << FEATURE_ACTIVITY_TRANSITIONS) | (1 << FEATURE_ACTION_MODE_OVERLAY); private static final Transition USE_DEFAULT_TRANSITION = new TransitionSet(); @@ -149,6 +150,8 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback { // mDecor itself, or a child of mDecor where the contents go. private ViewGroup mContentParent; + private ViewGroup mContentRoot; + SurfaceHolder.Callback2 mTakeSurfaceCallback; InputQueue.Callback mTakeInputQueueCallback; @@ -2153,6 +2156,7 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback { private int mLastTopInset = 0; private int mLastBottomInset = 0; + private int mLastRightInset = 0; private int mLastSystemUiVisibility = 0; @@ -2731,7 +2735,7 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback { @Override public WindowInsets onApplyWindowInsets(WindowInsets insets) { mFrameOffsets.set(insets.getSystemWindowInsets()); - updateColorViews(insets); + insets = updateColorViews(insets); insets = updateStatusGuard(insets); updateNavigationGuard(insets); if (getForeground() != null) { @@ -2748,8 +2752,12 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback { private WindowInsets updateColorViews(WindowInsets insets) { if (!mIsFloating && ActivityManager.isHighEndGfx()) { if (insets != null) { - mLastTopInset = insets.getStableInsetTop(); - mLastBottomInset = insets.getStableInsetBottom(); + mLastTopInset = Math.min(insets.getStableInsetTop(), + insets.getSystemWindowInsetTop()); + mLastBottomInset = Math.min(insets.getStableInsetBottom(), + insets.getSystemWindowInsetBottom()); + mLastRightInset = Math.min(insets.getStableInsetRight(), + insets.getSystemWindowInsetRight()); } mStatusColorView = updateColorViewInt(mStatusColorView, SYSTEM_UI_FLAG_FULLSCREEN, FLAG_TRANSLUCENT_STATUS, @@ -2764,8 +2772,39 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback { com.android.internal.R.id.navigationBarBackground, false /* hiddenByWindowFlag */); } + + WindowManager.LayoutParams attrs = getAttributes(); + int sysUiVisibility = attrs.systemUiVisibility | attrs.subtreeSystemUiVisibility; + + // When we expand the window with FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS, we still need + // to ensure that the rest of the view hierarchy doesn't notice it, unless they've + // explicitly asked for it. + + boolean consumingNavBar = + (attrs.flags & FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS) != 0 + && (sysUiVisibility & SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION) == 0 + && (mLastSystemUiVisibility & SYSTEM_UI_FLAG_HIDE_NAVIGATION) == 0; + + int consumedRight = consumingNavBar ? mLastRightInset : 0; + int consumedBottom = consumingNavBar ? mLastBottomInset : 0; + + if (mContentRoot != null + && mContentRoot.getLayoutParams() instanceof MarginLayoutParams) { + MarginLayoutParams lp = (MarginLayoutParams) mContentRoot.getLayoutParams(); + if (lp.rightMargin != consumedRight || lp.bottomMargin != consumedBottom) { + lp.rightMargin = consumedRight; + lp.bottomMargin = consumedBottom; + mContentRoot.setLayoutParams(lp); + } + } + if (insets != null) { - insets = insets.consumeStableInsets(); + insets = insets.consumeStableInsets().replaceSystemWindowInsets( + insets.getSystemWindowInsetLeft(), + insets.getSystemWindowInsetTop(), + insets.getSystemWindowInsetRight() - consumedRight, + insets.getSystemWindowInsetBottom() - consumedBottom + ); } return insets; } @@ -3207,6 +3246,9 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback { if (a.getBoolean(R.styleable.Window_windowContentTransitions, false)) { requestFeature(FEATURE_CONTENT_TRANSITIONS); } + if (a.getBoolean(R.styleable.Window_windowActivityTransitions, false)) { + requestFeature(FEATURE_ACTIVITY_TRANSITIONS); + } final WindowManager windowService = (WindowManager) getContext().getSystemService( Context.WINDOW_SERVICE); @@ -3377,6 +3419,7 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback { View in = mLayoutInflater.inflate(layoutResource, null); decor.addView(in, new ViewGroup.LayoutParams(MATCH_PARENT, MATCH_PARENT)); + mContentRoot = (ViewGroup) in; ViewGroup contentParent = (ViewGroup)findViewById(ID_ANDROID_CONTENT); if (contentParent == null) { @@ -3516,7 +3559,7 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback { // Only inflate or create a new TransitionManager if the caller hasn't // already set a custom one. - if (hasFeature(FEATURE_CONTENT_TRANSITIONS)) { + if (hasFeature(FEATURE_ACTIVITY_TRANSITIONS)) { if (mTransitionManager == null) { final int transitionRes = getWindowStyle().getResourceId( R.styleable.Window_windowContentTransitionManager, diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java index 9daa190..4713a98 100644 --- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java +++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java @@ -439,6 +439,7 @@ public class PhoneWindowManager implements WindowManagerPolicy { WindowState mTopFullscreenOpaqueWindowState; HashSet<IApplicationToken> mAppsToBeHidden = new HashSet<IApplicationToken>(); + HashSet<IApplicationToken> mAppsThatDismissKeyguard = new HashSet<IApplicationToken>(); boolean mTopIsFullscreen; boolean mForceStatusBar; boolean mForceStatusBarFromKeyguard; @@ -1520,8 +1521,7 @@ public class PhoneWindowManager implements WindowManagerPolicy { if (ActivityManager.isHighEndGfx() && (attrs.flags & FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS) != 0) { - attrs.subtreeSystemUiVisibility |= View.SYSTEM_UI_FLAG_LAYOUT_STABLE - | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN + attrs.subtreeSystemUiVisibility |= View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION; } } @@ -1758,6 +1758,11 @@ public class PhoneWindowManager implements WindowManagerPolicy { } } + @Override + public WindowState getWinShowWhenLockedLw() { + return mWinShowWhenLocked; + } + /** {@inheritDoc} */ @Override public View addStartingWindow(IBinder appToken, String packageName, int theme, @@ -3751,6 +3756,7 @@ public class PhoneWindowManager implements WindowManagerPolicy { public void beginPostLayoutPolicyLw(int displayWidth, int displayHeight) { mTopFullscreenOpaqueWindowState = null; mAppsToBeHidden.clear(); + mAppsThatDismissKeyguard.clear(); mForceStatusBar = false; mForceStatusBarFromKeyguard = false; mForcingShowNavBar = false; @@ -3791,7 +3797,7 @@ public class PhoneWindowManager implements WindowManagerPolicy { mShowingLockscreen = true; } boolean appWindow = attrs.type >= FIRST_APPLICATION_WINDOW - && attrs.type <= LAST_APPLICATION_WINDOW; + && attrs.type < FIRST_SYSTEM_WINDOW; if (attrs.type == TYPE_DREAM) { // If the lockscreen was showing when the dream started then wait // for the dream to draw before hiding the lockscreen. @@ -3806,38 +3812,44 @@ public class PhoneWindowManager implements WindowManagerPolicy { final boolean dismissKeyguard = (fl & FLAG_DISMISS_KEYGUARD) != 0; final boolean secureKeyguard = isKeyguardSecure(); if (appWindow) { - if (showWhenLocked || (dismissKeyguard && !secureKeyguard)) { + final IApplicationToken appToken = win.getAppToken(); + if (showWhenLocked) { // Remove any previous windows with the same appToken. - mAppsToBeHidden.remove(win.getAppToken()); - if (mAppsToBeHidden.isEmpty() && showWhenLocked && - isKeyguardSecureIncludingHidden()) { + mAppsToBeHidden.remove(appToken); + mAppsThatDismissKeyguard.remove(appToken); + if (mAppsToBeHidden.isEmpty() && isKeyguardSecureIncludingHidden()) { mWinShowWhenLocked = win; mHideLockScreen = true; mForceStatusBarFromKeyguard = false; } + } else if (dismissKeyguard) { + if (secureKeyguard) { + mAppsToBeHidden.add(appToken); + } else { + mAppsToBeHidden.remove(appToken); + } + mAppsThatDismissKeyguard.add(appToken); } else { - mAppsToBeHidden.add(win.getAppToken()); + mAppsToBeHidden.add(appToken); } if (attrs.x == 0 && attrs.y == 0 && attrs.width == WindowManager.LayoutParams.MATCH_PARENT && attrs.height == WindowManager.LayoutParams.MATCH_PARENT) { if (DEBUG_LAYOUT) Slog.v(TAG, "Fullscreen window: " + win); mTopFullscreenOpaqueWindowState = win; - if (mAppsToBeHidden.isEmpty()) { - if (showWhenLocked) { - if (DEBUG_LAYOUT) Slog.v(TAG, - "Setting mHideLockScreen to true by win " + win); - mHideLockScreen = true; - mForceStatusBarFromKeyguard = false; - } - if (dismissKeyguard && mDismissKeyguard == DISMISS_KEYGUARD_NONE) { - if (DEBUG_LAYOUT) Slog.v(TAG, - "Setting mDismissKeyguard true by win " + win); - mDismissKeyguard = mWinDismissingKeyguard == win ? - DISMISS_KEYGUARD_CONTINUE : DISMISS_KEYGUARD_START; - mWinDismissingKeyguard = win; - mForceStatusBarFromKeyguard = mShowingLockscreen && secureKeyguard; - } + if (!mAppsThatDismissKeyguard.isEmpty() && + mDismissKeyguard == DISMISS_KEYGUARD_NONE) { + if (DEBUG_LAYOUT) Slog.v(TAG, + "Setting mDismissKeyguard true by win " + win); + mDismissKeyguard = mWinDismissingKeyguard == win ? + DISMISS_KEYGUARD_CONTINUE : DISMISS_KEYGUARD_START; + mWinDismissingKeyguard = win; + mForceStatusBarFromKeyguard = mShowingLockscreen && secureKeyguard; + } else if (mAppsToBeHidden.isEmpty() && showWhenLocked) { + if (DEBUG_LAYOUT) Slog.v(TAG, + "Setting mHideLockScreen to true by win " + win); + mHideLockScreen = true; + mForceStatusBarFromKeyguard = false; } if ((fl & FLAG_ALLOW_LOCK_WHILE_SCREEN_ON) != 0) { mAllowLockscreenWhenOn = true; diff --git a/services/core/java/com/android/server/AlarmManagerService.java b/services/core/java/com/android/server/AlarmManagerService.java index b04cc19..7716385 100644 --- a/services/core/java/com/android/server/AlarmManagerService.java +++ b/services/core/java/com/android/server/AlarmManagerService.java @@ -127,6 +127,7 @@ class AlarmManagerService extends SystemService { long mLastAlarmDeliveryTime; long mStartCurrentDelayTime; long mNextNonWakeupDeliveryTime; + int mNumTimeChanged; private final SparseArray<AlarmManager.AlarmClockInfo> mNextAlarmClockForUser = new SparseArray<>(); @@ -821,6 +822,7 @@ class AlarmManagerService extends SystemService { pw.print(" = "); pw.println(sdf.format(new Date(nextNonWakeupRTC))); pw.print("Next wakeup: "); TimeUtils.formatDuration(mNextWakeup, nowELAPSED, pw); pw.print(" = "); pw.println(sdf.format(new Date(nextWakeupRTC))); + pw.print("Num time change events: "); pw.println(mNumTimeChanged); if (mAlarmBatches.size() > 0) { pw.println(); @@ -1619,6 +1621,9 @@ class AlarmManagerService extends SystemService { removeImpl(mTimeTickSender); rebatchAllAlarms(); mClockReceiver.scheduleTimeTickEvent(); + synchronized (mLock) { + mNumTimeChanged++; + } Intent intent = new Intent(Intent.ACTION_TIME_CHANGED); intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING | Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT); diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index a490ac6..2885b83 100755 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -14645,13 +14645,10 @@ public final class ActivityManagerService extends ActivityManagerNative } } else if ("system".equals(componentProcessName)) { result = true; - } else if (UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID) - && (flags & ServiceInfo.FLAG_SINGLE_USER) != 0) { - // Phone app is allowed to export singleuser providers. - result = true; - } else { - // App with pre-defined UID, check if it's a persistent app - result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0; + } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) { + // Phone app and persistent apps are allowed to export singleuser providers. + result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID) + || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0; } if (DEBUG_MU) { Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo diff --git a/services/core/java/com/android/server/am/ProcessList.java b/services/core/java/com/android/server/am/ProcessList.java index 1287dce..80d0510 100644 --- a/services/core/java/com/android/server/am/ProcessList.java +++ b/services/core/java/com/android/server/am/ProcessList.java @@ -21,6 +21,7 @@ import java.io.OutputStream; import java.nio.ByteBuffer; import android.app.ActivityManager; +import android.os.Build; import android.os.SystemClock; import com.android.internal.util.MemInfoReader; import com.android.server.wm.WindowManagerService; @@ -230,21 +231,31 @@ final class ProcessList { Slog.i("XXXXXX", "minfree_adj=" + minfree_adj + " minfree_abs=" + minfree_abs); } + final boolean is64bit = Build.SUPPORTED_64_BIT_ABIS.length > 0; + for (int i=0; i<mOomAdj.length; i++) { int low = mOomMinFreeLow[i]; int high = mOomMinFreeHigh[i]; mOomMinFree[i] = (int)(low + ((high-low)*scale)); + if (is64bit) { + // On 64 bit devices, we consume more baseline RAM, because 64 bit is cool! + // To avoid being all pagey and stuff, scale up the memory levels to + // give us some breathing room. + mOomMinFree[i] = (3*mOomMinFree[i])/2; + } } if (minfree_abs >= 0) { for (int i=0; i<mOomAdj.length; i++) { - mOomMinFree[i] = (int)((float)minfree_abs * mOomMinFree[i] / mOomMinFree[mOomAdj.length - 1]); + mOomMinFree[i] = (int)((float)minfree_abs * mOomMinFree[i] + / mOomMinFree[mOomAdj.length - 1]); } } if (minfree_adj != 0) { for (int i=0; i<mOomAdj.length; i++) { - mOomMinFree[i] += (int)((float)minfree_adj * mOomMinFree[i] / mOomMinFree[mOomAdj.length - 1]); + mOomMinFree[i] += (int)((float)minfree_adj * mOomMinFree[i] + / mOomMinFree[mOomAdj.length - 1]); if (mOomMinFree[i] < 0) { mOomMinFree[i] = 0; } diff --git a/services/core/java/com/android/server/am/TaskPersister.java b/services/core/java/com/android/server/am/TaskPersister.java index 3cc406b..b21af48 100644 --- a/services/core/java/com/android/server/am/TaskPersister.java +++ b/services/core/java/com/android/server/am/TaskPersister.java @@ -347,6 +347,10 @@ public class TaskPersister { private static void removeObsoleteFiles(ArraySet<Integer> persistentTaskIds, File[] files) { if (DEBUG) Slog.d(TAG, "removeObsoleteFile: persistentTaskIds=" + persistentTaskIds + " files=" + files); + if (files == null) { + Slog.e(TAG, "File error accessing recents directory (too many files open?)."); + return; + } for (int fileNdx = 0; fileNdx < files.length; ++fileNdx) { File file = files[fileNdx]; String filename = file.getName(); diff --git a/services/core/java/com/android/server/hdmi/Constants.java b/services/core/java/com/android/server/hdmi/Constants.java index 6ce235b..5823f47 100644 --- a/services/core/java/com/android/server/hdmi/Constants.java +++ b/services/core/java/com/android/server/hdmi/Constants.java @@ -255,37 +255,5 @@ final class Constants { // values which denotes the device type in HDMI Spec 1.4. static final String PROPERTY_DEVICE_TYPE = "ro.hdmi.device_type"; - // -------------------------------------------------- - // MHL sub command message types. - static final int MHL_MSG_MSGE = 0x02; - static final int MHL_MSG_RCP = 0x10; - static final int MHL_MSG_RCPK = 0x11; - static final int MHL_MSG_RCPE = 0x12; - static final int MHL_MSG_RAP = 0x20; - static final int MHL_MSG_RAPK = 0x21; - - // MHL RAP messages. - static final int MHL_RAP_ACTION_POLL = 0x00; - static final int MHL_RAP_ACTION_CONTENT_ON = 0x10; - static final int MHL_RAP_ACTION_CONTENT_OFF = 0x11; - - // MHL RAPK messages. - static final int MHL_RAPK_NO_ERROR = 0x00; - static final int MHL_RAPK_UNRECOGNIZED_ACTION = 0x01; - static final int MHL_RAPK_UNSUPPORTED_ACTION = 0x02; - static final int MHL_RAPK_RESPONDER_BUSY = 0x03; - - static final int MHL_INVALID_ADOPTER_ID = -1; - static final int MHL_INVALID_DEVICE_ID = -1; - - static final int MHL_CBUS_MODE_OCBUS = 1; - static final int MHL_CBUS_MODE_ECBUS_S = 2; - static final int MHL_CBUS_MODE_ECBUS_D = 3; - - // MHL RCPE messages - static final int MHL_RCPE_NO_ERROR = 0x00; - static final int MHL_RCPE_INEFFECTIVE_KEYCODE = 0x01; - static final int MHL_RCPE_RESPONDER_BUSY = 0x02; - private Constants() { /* cannot be instantiated */ } } diff --git a/services/core/java/com/android/server/hdmi/HdmiCecController.java b/services/core/java/com/android/server/hdmi/HdmiCecController.java index c5a6dbd..0e8788a 100644 --- a/services/core/java/com/android/server/hdmi/HdmiCecController.java +++ b/services/core/java/com/android/server/hdmi/HdmiCecController.java @@ -32,6 +32,7 @@ import com.android.server.hdmi.HdmiControlService.DevicePollingCallback; import libcore.util.EmptyArray; import java.util.ArrayList; +import java.util.LinkedList; import java.util.List; /** @@ -367,7 +368,8 @@ final class HdmiCecController { // Extract polling candidates. No need to poll against local devices. List<Integer> pollingCandidates = pickPollCandidates(pickStrategy); - runDevicePolling(sourceAddress, pollingCandidates, retryCount, callback); + ArrayList<Integer> allocated = new ArrayList<>(); + runDevicePolling(sourceAddress, pollingCandidates, retryCount, callback, allocated); } /** @@ -395,7 +397,7 @@ final class HdmiCecController { } int iterationStrategy = pickStrategy & Constants.POLL_ITERATION_STRATEGY_MASK; - ArrayList<Integer> pollingCandidates = new ArrayList<>(); + LinkedList<Integer> pollingCandidates = new LinkedList<>(); switch (iterationStrategy) { case Constants.POLL_ITERATION_IN_ORDER: for (int i = Constants.ADDR_TV; i <= Constants.ADDR_SPECIFIC_USE; ++i) { @@ -430,26 +432,32 @@ final class HdmiCecController { @ServiceThreadOnly private void runDevicePolling(final int sourceAddress, final List<Integer> candidates, final int retryCount, - final DevicePollingCallback callback) { + final DevicePollingCallback callback, final List<Integer> allocated) { assertRunOnServiceThread(); + if (candidates.isEmpty()) { + if (callback != null) { + HdmiLogger.debug("[P]:AllocatedAddress=%s", allocated.toString()); + callback.onPollingFinished(allocated); + } + return; + } + + final Integer candidate = candidates.remove(0); + // Proceed polling action for the next address once polling action for the + // previous address is done. runOnIoThread(new Runnable() { @Override public void run() { - final ArrayList<Integer> allocated = new ArrayList<>(); - for (Integer address : candidates) { - if (sendPollMessage(sourceAddress, address, retryCount)) { - allocated.add(address); - } - } - HdmiLogger.debug("[P]:Allocated Address=" + allocated); - if (callback != null) { - runOnServiceThread(new Runnable() { - @Override - public void run() { - callback.onPollingFinished(allocated); - } - }); + if (sendPollMessage(sourceAddress, candidate, retryCount)) { + allocated.add(candidate); } + runOnServiceThread(new Runnable() { + @Override + public void run() { + runDevicePolling(sourceAddress, candidates, retryCount, callback, + allocated); + } + }); } }); } diff --git a/services/core/java/com/android/server/hdmi/HdmiCecLocalDevice.java b/services/core/java/com/android/server/hdmi/HdmiCecLocalDevice.java index c00c5d0..41ac589 100644 --- a/services/core/java/com/android/server/hdmi/HdmiCecLocalDevice.java +++ b/services/core/java/com/android/server/hdmi/HdmiCecLocalDevice.java @@ -263,7 +263,9 @@ abstract class HdmiCecLocalDevice { case Constants.MESSAGE_GIVE_DEVICE_POWER_STATUS: return handleGiveDevicePowerStatus(message); case Constants.MESSAGE_MENU_REQUEST: - return handleGiveDeviceMenuStatus(message); + return handleMenuRequest(message); + case Constants.MESSAGE_MENU_STATUS: + return handleMenuStatus(message); case Constants.MESSAGE_VENDOR_COMMAND: return handleVendorCommand(message); case Constants.MESSAGE_VENDOR_COMMAND_WITH_ID: @@ -503,16 +505,24 @@ abstract class HdmiCecLocalDevice { return true; } - protected boolean handleGiveDeviceMenuStatus(HdmiCecMessage message) { + protected boolean handleMenuRequest(HdmiCecMessage message) { // Always report menu active to receive Remote Control. mService.sendCecCommand(HdmiCecMessageBuilder.buildReportMenuStatus( mAddress, message.getSource(), Constants.MENU_STATE_ACTIVATED)); return true; } + protected boolean handleMenuStatus(HdmiCecMessage message) { + return false; + } + protected boolean handleVendorCommand(HdmiCecMessage message) { - mService.invokeVendorCommandListeners(mDeviceType, message.getSource(), - message.getParams(), false); + if (!mService.invokeVendorCommandListeners(mDeviceType, message.getSource(), + message.getParams(), false)) { + // Vendor command listener may not have been registered yet. Respond with + // <Feature Abort> [NOT_IN_CORRECT_MODE] so that the sender can try again later. + mService.maySendFeatureAbortCommand(message, Constants.ABORT_NOT_IN_CORRECT_MODE); + } return true; } @@ -520,7 +530,10 @@ abstract class HdmiCecLocalDevice { byte[] params = message.getParams(); int vendorId = HdmiUtils.threeBytesToInt(params); if (vendorId == mService.getVendorId()) { - mService.invokeVendorCommandListeners(mDeviceType, message.getSource(), params, true); + if (!mService.invokeVendorCommandListeners(mDeviceType, message.getSource(), params, + true)) { + mService.maySendFeatureAbortCommand(message, Constants.ABORT_NOT_IN_CORRECT_MODE); + } } else if (message.getDestination() != Constants.ADDR_BROADCAST && message.getSource() != Constants.ADDR_UNREGISTERED) { Slog.v(TAG, "Wrong direct vendor command. Replying with <Feature Abort>"); @@ -531,6 +544,10 @@ abstract class HdmiCecLocalDevice { return true; } + protected void sendStandby(int deviceId) { + // Do nothing. + } + protected boolean handleSetOsdName(HdmiCecMessage message) { // The default behavior of <Set Osd Name> is doing nothing. return true; diff --git a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java index 58ccbdb..9033c38 100644 --- a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java +++ b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java @@ -1646,6 +1646,22 @@ final class HdmiCecLocalDeviceTv extends HdmiCecLocalDevice { } @Override + protected boolean handleMenuStatus(HdmiCecMessage message) { + // Do nothing and just return true not to prevent from responding <Feature Abort>. + return true; + } + + @Override + protected void sendStandby(int deviceId) { + HdmiDeviceInfo targetDevice = mDeviceInfos.get(deviceId); + if (targetDevice == null) { + return; + } + int targetAddress = targetDevice.getLogicalAddress(); + mService.sendCecCommand(HdmiCecMessageBuilder.buildStandby(mAddress, targetAddress)); + } + + @Override protected void dump(final IndentingPrintWriter pw) { super.dump(pw); pw.println("mArcEstablished: " + mArcEstablished); diff --git a/services/core/java/com/android/server/hdmi/HdmiCecMessageValidator.java b/services/core/java/com/android/server/hdmi/HdmiCecMessageValidator.java index 0b3d9fb..d703989 100644 --- a/services/core/java/com/android/server/hdmi/HdmiCecMessageValidator.java +++ b/services/core/java/com/android/server/hdmi/HdmiCecMessageValidator.java @@ -25,6 +25,11 @@ import android.util.SparseArray; public final class HdmiCecMessageValidator { private static final String TAG = "HdmiCecMessageValidator"; + static final int OK = 0; + static final int ERROR_SOURCE = 1; + static final int ERROR_DESTINATION = 2; + static final int ERROR_PARAMETER = 3; + private final HdmiControlService mService; interface ParameterValidator { @@ -140,7 +145,9 @@ public final class HdmiCecMessageValidator { addValidationInfo(Constants.MESSAGE_SET_OSD_STRING, maxLengthValidator, DEST_DIRECT); addValidationInfo(Constants.MESSAGE_SET_OSD_NAME, maxLengthValidator, DEST_DIRECT); - // TODO: Handle messages for the Device Menu Control. + // Messages for the Device Menu Control. + addValidationInfo(Constants.MESSAGE_MENU_REQUEST, oneByteValidator, DEST_DIRECT); + addValidationInfo(Constants.MESSAGE_MENU_STATUS, oneByteValidator, DEST_DIRECT); // Messages for the Remote Control Passthrough. // TODO: Parse the first parameter and determine if it can have the next parameter. @@ -178,39 +185,39 @@ public final class HdmiCecMessageValidator { mValidationInfo.append(opcode, new ValidationInfo(validator, addrType)); } - boolean isValid(HdmiCecMessage message) { + int isValid(HdmiCecMessage message) { int opcode = message.getOpcode(); ValidationInfo info = mValidationInfo.get(opcode); if (info == null) { HdmiLogger.warning("No validation information for the message: " + message); - return true; + return OK; } // Check the source field. if (message.getSource() == Constants.ADDR_UNREGISTERED && (info.addressType & SRC_UNREGISTERED) == 0) { HdmiLogger.warning("Unexpected source: " + message); - return false; + return ERROR_SOURCE; } // Check the destination field. if (message.getDestination() == Constants.ADDR_BROADCAST) { if ((info.addressType & DEST_BROADCAST) == 0) { HdmiLogger.warning("Unexpected broadcast message: " + message); - return false; + return ERROR_DESTINATION; } } else { // Direct addressing. if ((info.addressType & DEST_DIRECT) == 0) { HdmiLogger.warning("Unexpected direct message: " + message); - return false; + return ERROR_DESTINATION; } } // Check the parameter type. if (!info.parameterValidator.isValid(message.getParams())) { HdmiLogger.warning("Unexpected parameters: " + message); - return false; + return ERROR_PARAMETER; } - return true; + return OK; } private static class FixedLengthValidator implements ParameterValidator { diff --git a/services/core/java/com/android/server/hdmi/HdmiControlService.java b/services/core/java/com/android/server/hdmi/HdmiControlService.java index 5cd7c01..96823e1 100644 --- a/services/core/java/com/android/server/hdmi/HdmiControlService.java +++ b/services/core/java/com/android/server/hdmi/HdmiControlService.java @@ -43,7 +43,7 @@ import android.hardware.hdmi.IHdmiControlService; import android.hardware.hdmi.IHdmiDeviceEventListener; import android.hardware.hdmi.IHdmiHotplugEventListener; import android.hardware.hdmi.IHdmiInputChangeListener; -import android.hardware.hdmi.IHdmiMhlScratchpadCommandListener; +import android.hardware.hdmi.IHdmiMhlVendorCommandListener; import android.hardware.hdmi.IHdmiRecordListener; import android.hardware.hdmi.IHdmiSystemAudioModeChangeListener; import android.hardware.hdmi.IHdmiVendorCommandListener; @@ -247,10 +247,10 @@ public final class HdmiControlService extends SystemService { @GuardedBy("mLock") private boolean mMhlInputChangeEnabled; - // List of records for MHL Scratchpad command listener to handle the caller killed in action. + // List of records for MHL Vendor command listener to handle the caller killed in action. @GuardedBy("mLock") - private final ArrayList<HdmiMhlScratchpadCommandListenerRecord> - mScratchpadCommandListenerRecords = new ArrayList<>(); + private final ArrayList<HdmiMhlVendorCommandListenerRecord> + mMhlVendorCommandListenerRecords = new ArrayList<>(); @GuardedBy("mLock") private List<HdmiDeviceInfo> mMhlDevices; @@ -651,7 +651,7 @@ public final class HdmiControlService extends SystemService { @ServiceThreadOnly void sendCecCommand(HdmiCecMessage command, @Nullable SendMessageCallback callback) { assertRunOnServiceThread(); - if (mMessageValidator.isValid(command)) { + if (mMessageValidator.isValid(command) == HdmiCecMessageValidator.OK) { mCecController.sendCommand(command, callback); } else { HdmiLogger.error("Invalid message type:" + command); @@ -682,8 +682,13 @@ public final class HdmiControlService extends SystemService { @ServiceThreadOnly boolean handleCecCommand(HdmiCecMessage message) { assertRunOnServiceThread(); - if (!mMessageValidator.isValid(message)) { - return false; + int errorCode = mMessageValidator.isValid(message); + if (errorCode != HdmiCecMessageValidator.OK) { + // We'll not response on the messages with the invalid source or destination. + if (errorCode == HdmiCecMessageValidator.ERROR_PARAMETER) { + maySendFeatureAbortCommand(message, Constants.ABORT_INVALID_OPERAND); + } + return true; } return dispatchMessageToLocalDevice(message); } @@ -814,45 +819,21 @@ public final class HdmiControlService extends SystemService { } @ServiceThreadOnly - void sendMhlSubcommand(int portId, HdmiMhlSubcommand command) { - assertRunOnServiceThread(); - sendMhlSubcommand(portId, command, null); - } - - @ServiceThreadOnly - void sendMhlSubcommand(int portId, HdmiMhlSubcommand command, SendMessageCallback callback) { - assertRunOnServiceThread(); - mMhlController.sendSubcommand(portId, command, callback); - } - - @ServiceThreadOnly - boolean handleMhlSubcommand(int portId, HdmiMhlSubcommand message) { - assertRunOnServiceThread(); - - HdmiMhlLocalDevice device = mMhlController.getLocalDevice(portId); - if (device != null) { - return device.handleSubcommand(message); - } - Slog.w(TAG, "No mhl device exists[portId:" + portId + ", message:" + message); - return false; - } - - @ServiceThreadOnly void handleMhlHotplugEvent(int portId, boolean connected) { assertRunOnServiceThread(); if (connected) { - HdmiMhlLocalDevice newDevice = new HdmiMhlLocalDevice(this, portId); - HdmiMhlLocalDevice oldDevice = mMhlController.addLocalDevice(newDevice); + HdmiMhlLocalDeviceStub newDevice = new HdmiMhlLocalDeviceStub(this, portId); + HdmiMhlLocalDeviceStub oldDevice = mMhlController.addLocalDevice(newDevice); if (oldDevice != null) { oldDevice.onDeviceRemoved(); Slog.i(TAG, "Old device of port " + portId + " is removed"); } } else { - HdmiMhlLocalDevice device = mMhlController.removeLocalDevice(portId); + HdmiMhlLocalDeviceStub 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. + // There is no explicit event for device removal. + // Hence we remove the device on hotplug event. HdmiDeviceInfo deviceInfo = device.getInfo(); if (deviceInfo != null) { invokeDeviceEventListeners(deviceInfo, DEVICE_EVENT_REMOVE_DEVICE); @@ -866,40 +847,40 @@ public final class HdmiControlService extends SystemService { } @ServiceThreadOnly - void handleMhlCbusModeChanged(int portId, int cbusmode) { + void handleMhlBusModeChanged(int portId, int busmode) { assertRunOnServiceThread(); - HdmiMhlLocalDevice device = mMhlController.getLocalDevice(portId); + HdmiMhlLocalDeviceStub device = mMhlController.getLocalDevice(portId); if (device != null) { - device.setCbusMode(cbusmode); + device.setBusMode(busmode); } else { - Slog.w(TAG, "No mhl device exists for cbus mode change[portId:" + portId + - ", cbusmode:" + cbusmode + "]"); + Slog.w(TAG, "No mhl device exists for bus mode change[portId:" + portId + + ", busmode:" + busmode + "]"); } } @ServiceThreadOnly - void handleMhlVbusOvercurrent(int portId, boolean on) { + void handleMhlBusOvercurrent(int portId, boolean on) { assertRunOnServiceThread(); - HdmiMhlLocalDevice device = mMhlController.getLocalDevice(portId); + HdmiMhlLocalDeviceStub device = mMhlController.getLocalDevice(portId); if (device != null) { - device.onVbusOvercurrentDetected(on); + device.onBusOvercurrentDetected(on); } else { - Slog.w(TAG, "No mhl device exists for vbus overcurrent event[portId:" + portId + "]"); + Slog.w(TAG, "No mhl device exists for bus overcurrent event[portId:" + portId + "]"); } } @ServiceThreadOnly - void handleMhlCapabilityRegisterChanged(int portId, int adopterId, int deviceId) { + void handleMhlDeviceStatusChanged(int portId, int adopterId, int deviceId) { assertRunOnServiceThread(); - HdmiMhlLocalDevice device = mMhlController.getLocalDevice(portId); + HdmiMhlLocalDeviceStub device = mMhlController.getLocalDevice(portId); - // Hotplug event should already have been called before capability register change event. + // Hotplug event should already have been called before device status change event. if (device != null) { - device.setCapabilityRegister(adopterId, deviceId); + device.setDeviceStatusChange(adopterId, deviceId); invokeDeviceEventListeners(device.getInfo(), DEVICE_EVENT_ADD_DEVICE); updateSafeMhlInput(); } else { - Slog.w(TAG, "No mhl device exists for capability register change event[portId:" + Slog.w(TAG, "No mhl device exists for device status event[portId:" + portId + ", adopterId:" + adopterId + ", deviceId:" + deviceId + "]"); } } @@ -908,9 +889,9 @@ public final class HdmiControlService extends SystemService { private void updateSafeMhlInput() { assertRunOnServiceThread(); List<HdmiDeviceInfo> inputs = Collections.emptyList(); - SparseArray<HdmiMhlLocalDevice> devices = mMhlController.getAllLocalDevices(); + SparseArray<HdmiMhlLocalDeviceStub> devices = mMhlController.getAllLocalDevices(); for (int i = 0; i < devices.size(); ++i) { - HdmiMhlLocalDevice device = devices.valueAt(i); + HdmiMhlLocalDeviceStub device = devices.valueAt(i); HdmiDeviceInfo info = device.getInfo(); if (info != null) { if (inputs.isEmpty()) { @@ -928,16 +909,16 @@ public final class HdmiControlService extends SystemService { return mMhlDevices; } - private class HdmiMhlScratchpadCommandListenerRecord implements IBinder.DeathRecipient { - private final IHdmiMhlScratchpadCommandListener mListener; + private class HdmiMhlVendorCommandListenerRecord implements IBinder.DeathRecipient { + private final IHdmiMhlVendorCommandListener mListener; - public HdmiMhlScratchpadCommandListenerRecord(IHdmiMhlScratchpadCommandListener listener) { + public HdmiMhlVendorCommandListenerRecord(IHdmiMhlVendorCommandListener listener) { mListener = listener; } @Override public void binderDied() { - mScratchpadCommandListenerRecords.remove(this); + mMhlVendorCommandListenerRecords.remove(this); } } @@ -1072,7 +1053,7 @@ public final class HdmiControlService extends SystemService { invokeCallback(callback, HdmiControlManager.RESULT_SOURCE_NOT_AVAILABLE); return; } - HdmiMhlLocalDevice device = mMhlController.getLocalDeviceById(deviceId); + HdmiMhlLocalDeviceStub device = mMhlController.getLocalDeviceById(deviceId); if (device != null) { if (device.getPortId() == tv.getActivePortId()) { invokeCallback(callback, HdmiControlManager.RESULT_SUCCESS); @@ -1117,7 +1098,7 @@ public final class HdmiControlService extends SystemService { runOnServiceThread(new Runnable() { @Override public void run() { - HdmiMhlLocalDevice device = mMhlController.getLocalDevice(mActivePortId); + HdmiMhlLocalDeviceStub device = mMhlController.getLocalDevice(mActivePortId); if (device != null) { device.sendKeyEvent(keyCode, isPressed); return; @@ -1340,6 +1321,22 @@ public final class HdmiControlService extends SystemService { } @Override + public void sendStandby(final int deviceType, final int deviceId) { + enforceAccessPermission(); + runOnServiceThread(new Runnable() { + @Override + public void run() { + HdmiCecLocalDevice device = mCecController.getLocalDevice(deviceType); + if (device == null) { + Slog.w(TAG, "Local device not available"); + return; + } + device.sendStandby(deviceId); + } + }); + } + + @Override public void setHdmiRecordListener(IHdmiRecordListener listener) { HdmiControlService.this.setHdmiRecordListener(listener); } @@ -1403,7 +1400,7 @@ public final class HdmiControlService extends SystemService { } @Override - public void sendScratchpadCommand(final int portId, final int offset, final int length, + public void sendMhlVendorCommand(final int portId, final int offset, final int length, final byte[] data) { enforceAccessPermission(); runOnServiceThread(new Runnable() { @@ -1413,21 +1410,21 @@ public final class HdmiControlService extends SystemService { Slog.w(TAG, "Hdmi control is disabled."); return ; } - HdmiMhlLocalDevice device = mMhlController.getLocalDevice(portId); + HdmiMhlLocalDeviceStub device = mMhlController.getLocalDevice(portId); if (device == null) { Slog.w(TAG, "Invalid port id:" + portId); return; } - mMhlController.sendScratchpadCommand(portId, offset, length, data); + mMhlController.sendVendorCommand(portId, offset, length, data); } }); } @Override - public void addHdmiMhlScratchpadCommandListener( - IHdmiMhlScratchpadCommandListener listener) { + public void addHdmiMhlVendorCommandListener( + IHdmiMhlVendorCommandListener listener) { enforceAccessPermission(); - HdmiControlService.this.addHdmiMhlScratchpadCommandListener(listener); + HdmiControlService.this.addHdmiMhlVendorCommandListener(listener); } @Override @@ -1864,9 +1861,12 @@ public final class HdmiControlService extends SystemService { } } - void invokeVendorCommandListeners(int deviceType, int srcAddress, byte[] params, + boolean invokeVendorCommandListeners(int deviceType, int srcAddress, byte[] params, boolean hasVendorId) { synchronized (mLock) { + if (mVendorCommandListenerRecords.isEmpty()) { + return false; + } for (VendorCommandListenerRecord record : mVendorCommandListenerRecords) { if (record.mDeviceType != deviceType) { continue; @@ -1877,12 +1877,13 @@ public final class HdmiControlService extends SystemService { Slog.e(TAG, "Failed to notify vendor command reception", e); } } + return true; } } - private void addHdmiMhlScratchpadCommandListener(IHdmiMhlScratchpadCommandListener listener) { - HdmiMhlScratchpadCommandListenerRecord record = - new HdmiMhlScratchpadCommandListenerRecord(listener); + private void addHdmiMhlVendorCommandListener(IHdmiMhlVendorCommandListener listener) { + HdmiMhlVendorCommandListenerRecord record = + new HdmiMhlVendorCommandListenerRecord(listener); try { listener.asBinder().linkToDeath(record, 0); } catch (RemoteException e) { @@ -1891,18 +1892,17 @@ public final class HdmiControlService extends SystemService { } synchronized (mLock) { - mScratchpadCommandListenerRecords.add(record); + mMhlVendorCommandListenerRecords.add(record); } } - void invokeScratchpadCommandListeners(int portId, int offest, int length, byte[] data) { + void invokeMhlVendorCommandListeners(int portId, int offest, int length, byte[] data) { synchronized (mLock) { - for (HdmiMhlScratchpadCommandListenerRecord record : - mScratchpadCommandListenerRecords) { + for (HdmiMhlVendorCommandListenerRecord record : mMhlVendorCommandListenerRecords) { try { record.mListener.onReceived(portId, offest, length, data); } catch (RemoteException e) { - Slog.e(TAG, "Failed to notify scratchpad command", e); + Slog.e(TAG, "Failed to notify MHL vendor command", e); } } } @@ -2001,7 +2001,7 @@ public final class HdmiControlService extends SystemService { // the last port to go back to when turnoff command is received. Note that the last port // may not be the MHL-enabled one. In this case the device info to be passed to // input change listener should be the one describing the corresponding HDMI port. - HdmiMhlLocalDevice device = mMhlController.getLocalDevice(portId); + HdmiMhlLocalDeviceStub device = mMhlController.getLocalDevice(portId); HdmiDeviceInfo info = (device != null && device.getInfo() != null) ? device.getInfo() : mPortDeviceMap.get(portId); diff --git a/services/core/java/com/android/server/hdmi/HdmiMhlControllerStub.java b/services/core/java/com/android/server/hdmi/HdmiMhlControllerStub.java index c27cf18..708aee6 100644 --- a/services/core/java/com/android/server/hdmi/HdmiMhlControllerStub.java +++ b/services/core/java/com/android/server/hdmi/HdmiMhlControllerStub.java @@ -29,7 +29,7 @@ import com.android.server.hdmi.HdmiControlService.SendMessageCallback; */ final class HdmiMhlControllerStub { - private static final SparseArray<HdmiMhlLocalDevice> mLocalDevices = new SparseArray<>(); + private static final SparseArray<HdmiMhlLocalDeviceStub> mLocalDevices = new SparseArray<>(); private static final HdmiPortInfo[] EMPTY_PORT_INFO = new HdmiPortInfo[0]; private static final int INVALID_MHL_VERSION = 0; private static final int NO_SUPPORTED_FEATURES = 0; @@ -53,60 +53,49 @@ final class HdmiMhlControllerStub { } /** - * Return {@link HdmiMhlLocalDevice} matched with the given port id. + * Return {@link HdmiMhlLocalDeviceStub} matched with the given port id. * * @return null if has no matched port id */ - HdmiMhlLocalDevice getLocalDevice(int portId) { + HdmiMhlLocalDeviceStub getLocalDevice(int portId) { return null; } /** - * Return {@link HdmiMhlLocalDevice} matched with the given device id. + * Return {@link HdmiMhlLocalDeviceStub} matched with the given device id. * * @return null if has no matched id */ - HdmiMhlLocalDevice getLocalDeviceById(int deviceId) { + HdmiMhlLocalDeviceStub getLocalDeviceById(int deviceId) { return null; } - SparseArray<HdmiMhlLocalDevice> getAllLocalDevices() { + SparseArray<HdmiMhlLocalDeviceStub> getAllLocalDevices() { return mLocalDevices; } /** - * Remove a {@link HdmiMhlLocalDevice} matched with the given port id. + * Remove a {@link HdmiMhlLocalDeviceStub} matched with the given port id. * - * @return removed {@link HdmiMhlLocalDevice}. Return null if no matched port id. + * @return removed {@link HdmiMhlLocalDeviceStub}. Return null if no matched port id. */ - HdmiMhlLocalDevice removeLocalDevice(int portId) { + HdmiMhlLocalDeviceStub removeLocalDevice(int portId) { return null; } /** - * Add a new {@link HdmiMhlLocalDevice}. + * Add a new {@link HdmiMhlLocalDeviceStub}. * - * @return old {@link HdmiMhlLocalDevice} having same port id + * @return old {@link HdmiMhlLocalDeviceStub} having same port id */ - HdmiMhlLocalDevice addLocalDevice(HdmiMhlLocalDevice device) { + HdmiMhlLocalDeviceStub addLocalDevice(HdmiMhlLocalDeviceStub device) { return null; } void clearAllLocalDevices() { } - /** - * Send MHL MSC-Subcommand to the device connected to the given port. - */ - void sendSubcommand(int portId, HdmiMhlSubcommand command) { - } - - void sendSubcommand(final int portId, final HdmiMhlSubcommand command, - SendMessageCallback callback) { - } - - - void sendScratchpadCommand(int portId, int offset, int length, byte[] data) { + void sendVendorCommand(int portId, int offset, int length, byte[] data) { } void setOption(int flag, int value) { diff --git a/services/core/java/com/android/server/hdmi/HdmiMhlLocalDeviceStub.java b/services/core/java/com/android/server/hdmi/HdmiMhlLocalDeviceStub.java new file mode 100644 index 0000000..53a7c5c --- /dev/null +++ b/services/core/java/com/android/server/hdmi/HdmiMhlLocalDeviceStub.java @@ -0,0 +1,46 @@ +package com.android.server.hdmi; + +import android.hardware.hdmi.HdmiDeviceInfo; +import android.hardware.hdmi.IHdmiControlCallback; + +/** + * Stub class that models a logical mhl device hosted in this system. + */ +final class HdmiMhlLocalDeviceStub { + + private static final HdmiDeviceInfo INFO = new HdmiDeviceInfo( + Constants.INVALID_PHYSICAL_ADDRESS, Constants.INVALID_PORT_ID, -1, -1); + private final HdmiControlService mService; + private final int mPortId; + + protected HdmiMhlLocalDeviceStub(HdmiControlService service, int portId) { + mService = service; + mPortId = portId; + } + + void onDeviceRemoved() { + } + + HdmiDeviceInfo getInfo() { + return INFO; + } + + void setBusMode(int cbusmode) { + } + + void onBusOvercurrentDetected(boolean on) { + } + + void setDeviceStatusChange(int adopterId, int deviceId) { + } + + int getPortId() { + return mPortId; + } + + void turnOn(IHdmiControlCallback callback) { + } + + void sendKeyEvent(int keycode, boolean isPressed) { + } +} diff --git a/services/core/java/com/android/server/hdmi/MhlConstants.java b/services/core/java/com/android/server/hdmi/MhlConstants.java new file mode 100644 index 0000000..fe479f3 --- /dev/null +++ b/services/core/java/com/android/server/hdmi/MhlConstants.java @@ -0,0 +1,40 @@ +package com.android.server.hdmi; + +/** + * Defines constants related to MHL protocol internal implementation. + */ +final class MhlConstants { + // -------------------------------------------------- + // MHL sub command message types. + static final int MSG_MSGE = 0x02; + static final int MSG_RCP = 0x10; + static final int MSG_RCPK = 0x11; + static final int MSG_RCPE = 0x12; + static final int MSG_RAP = 0x20; + static final int MSG_RAPK = 0x21; + + // MHL RAP messages. + static final int RAP_ACTION_POLL = 0x00; + static final int RAP_ACTION_CONTENT_ON = 0x10; + static final int RAP_ACTION_CONTENT_OFF = 0x11; + + // MHL RAPK messages. + static final int RAPK_NO_ERROR = 0x00; + static final int RAPK_UNRECOGNIZED_ACTION = 0x01; + static final int RAPK_UNSUPPORTED_ACTION = 0x02; + static final int RAPK_RESPONDER_BUSY = 0x03; + + static final int INVALID_ADOPTER_ID = -1; + static final int INVALID_DEVICE_ID = -1; + + static final int CBUS_MODE_OCBUS = 1; + static final int CBUS_MODE_ECBUS_S = 2; + static final int CBUS_MODE_ECBUS_D = 3; + + // MHL RCPE messages + static final int RCPE_NO_ERROR = 0x00; + static final int RCPE_INEFFECTIVE_KEYCODE = 0x01; + static final int RCPE_RESPONDER_BUSY = 0x02; + + private MhlConstants() { /* cannot be instantiated */ } +} diff --git a/services/core/java/com/android/server/notification/ManagedServices.java b/services/core/java/com/android/server/notification/ManagedServices.java index f647037..13fbf6c 100644 --- a/services/core/java/com/android/server/notification/ManagedServices.java +++ b/services/core/java/com/android/server/notification/ManagedServices.java @@ -87,6 +87,10 @@ abstract public class ManagedServices { // Just the packages from mEnabledServicesForCurrentProfiles private ArraySet<String> mEnabledServicesPackageNames = new ArraySet<String>(); + // Kept to de-dupe user change events (experienced after boot, when we receive a settings and a + // user change). + private int[] mLastSeenProfileIds; + public ManagedServices(Context context, Handler handler, Object mutex, UserProfiles userProfiles) { mContext = context; @@ -159,6 +163,15 @@ abstract public class ManagedServices { } } + public void onUserSwitched() { + if (DEBUG) Slog.d(TAG, "onUserSwitched"); + if (Arrays.equals(mLastSeenProfileIds, mUserProfiles.getCurrentProfileIds())) { + if (DEBUG) Slog.d(TAG, "Current profile IDs didn't change, skipping rebindServices()."); + return; + } + rebindServices(); + } + public ManagedServiceInfo checkServiceTokenLocked(IInterface service) { checkNotNull(service); final IBinder token = service.asBinder(); @@ -321,6 +334,8 @@ abstract public class ManagedServices { registerService(component, userIds[i]); } } + + mLastSeenProfileIds = mUserProfiles.getCurrentProfileIds(); } /** @@ -523,6 +538,8 @@ abstract public class ManagedServices { private void update(Uri uri) { if (uri == null || mSecureSettingsUri.equals(uri)) { + if (DEBUG) Slog.d(TAG, "Setting changed: mSecureSettingsUri=" + mSecureSettingsUri + + " / uri=" + uri); rebindServices(); } } diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java index c09eff8..14587e6 100644 --- a/services/core/java/com/android/server/notification/NotificationManagerService.java +++ b/services/core/java/com/android/server/notification/NotificationManagerService.java @@ -718,6 +718,9 @@ public class NotificationManagerService extends SystemService { // reload per-user settings mSettingsObserver.update(null); mUserProfiles.updateCache(context); + // Refresh managed services + mConditionProviders.onUserSwitched(); + mListeners.onUserSwitched(); } else if (action.equals(Intent.ACTION_USER_ADDED)) { mUserProfiles.updateCache(context); } @@ -1236,17 +1239,16 @@ public class NotificationManagerService extends SystemService { final int N = keys.length; for (int i = 0; i < N; i++) { NotificationRecord r = mNotificationsByKey.get(keys[i]); + if (r == null) continue; final int userId = r.sbn.getUserId(); if (userId != info.userid && userId != UserHandle.USER_ALL && !mUserProfiles.isCurrentProfile(userId)) { throw new SecurityException("Disallowed call from listener: " + info.service); } - if (r != null) { - cancelNotificationFromListenerLocked(info, callingUid, callingPid, - r.sbn.getPackageName(), r.sbn.getTag(), r.sbn.getId(), - userId); - } + cancelNotificationFromListenerLocked(info, callingUid, callingPid, + r.sbn.getPackageName(), r.sbn.getTag(), r.sbn.getId(), + userId); } } else { cancelAllLocked(callingUid, callingPid, info.userid, @@ -1472,14 +1474,7 @@ public class NotificationManagerService extends SystemService { @Override public boolean matchesCallFilter(Bundle extras) { enforceSystemOrSystemUI("INotificationManager.matchesCallFilter"); - return matchesCallFilterAsUser(extras, Binder.getCallingUid()); - } - - @Override - public boolean matchesCallFilterAsUser(Bundle extras, int userId) { - enforceSystemOrSystemUI("INotificationManager.matchesCallFilter"); - UserHandle userHandle = new UserHandle(userId); - return mZenModeHelper.matchesCallFilter(userHandle, extras, + return mZenModeHelper.matchesCallFilter(UserHandle.getCallingUserHandle(), extras, mRankingHelper.findExtractor(ValidateNotificationPeople.class)); } }; diff --git a/services/core/java/com/android/server/notification/ValidateNotificationPeople.java b/services/core/java/com/android/server/notification/ValidateNotificationPeople.java index f266916..d49dc9a 100644 --- a/services/core/java/com/android/server/notification/ValidateNotificationPeople.java +++ b/services/core/java/com/android/server/notification/ValidateNotificationPeople.java @@ -112,6 +112,7 @@ public class ValidateNotificationPeople implements NotificationSignalExtractor { } public float getContactAffinity(UserHandle userHandle, Bundle extras) { + if (DEBUG) Slog.d(TAG, "checking affinity for " + userHandle); if (extras == null) return NONE; final String key = Long.toString(System.nanoTime()); final float[] affinityOut = new float[1]; diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index 3e5d514..f09d789 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -1793,19 +1793,17 @@ public class PackageManagerService extends IPackageManager.Stub { void cleanupInstallFailedPackage(PackageSetting ps) { Slog.i(TAG, "Cleaning up incompletely installed app: " + ps.name); removeDataDirsLI(ps.name); - - // TODO: try cleaning up codePath directory contents first, since it - // might be a cluster - if (ps.codePath != null) { - if (!ps.codePath.delete()) { - Slog.w(TAG, "Unable to remove old code file: " + ps.codePath); + if (ps.codePath.isDirectory()) { + FileUtils.deleteContents(ps.codePath); } + ps.codePath.delete(); } - if (ps.resourcePath != null) { - if (!ps.resourcePath.delete() && !ps.resourcePath.equals(ps.codePath)) { - Slog.w(TAG, "Unable to remove old code file: " + ps.resourcePath); + if (ps.resourcePath != null && !ps.resourcePath.equals(ps.codePath)) { + if (ps.resourcePath.isDirectory()) { + FileUtils.deleteContents(ps.resourcePath); } + ps.resourcePath.delete(); } mSettings.removePackageLPw(ps.name); } @@ -4958,6 +4956,21 @@ public class PackageManagerService extends IPackageManager.Stub { private PackageParser.Package scanPackageLI(PackageParser.Package pkg, int parseFlags, int scanFlags, long currentTime, UserHandle user) throws PackageManagerException { + boolean success = false; + try { + final PackageParser.Package res = scanPackageDirtyLI(pkg, parseFlags, scanFlags, + currentTime, user); + success = true; + return res; + } finally { + if (!success && (scanFlags & SCAN_DELETE_DATA_ON_FAILURES) != 0) { + removeDataDirsLI(pkg.packageName); + } + } + } + + private PackageParser.Package scanPackageDirtyLI(PackageParser.Package pkg, int parseFlags, + int scanFlags, long currentTime, UserHandle user) throws PackageManagerException { final File scanFile = new File(pkg.codePath); if (pkg.applicationInfo.getCodePath() == null || pkg.applicationInfo.getResourcePath() == null) { @@ -5264,7 +5277,8 @@ public class PackageManagerService extends IPackageManager.Stub { File dataPath; if (mPlatformPackage == pkg) { // The system package is special. - dataPath = new File (Environment.getDataDirectory(), "system"); + dataPath = new File(Environment.getDataDirectory(), "system"); + pkg.applicationInfo.dataDir = dataPath.getPath(); } else { @@ -5272,7 +5286,6 @@ public class PackageManagerService extends IPackageManager.Stub { dataPath = getDataPathForPackage(pkg.packageName, 0); boolean uidError = false; - if (dataPath.exists()) { int currentUid = 0; try { @@ -5599,13 +5612,9 @@ public class PackageManagerService extends IPackageManager.Stub { pkg, forceDex, (scanFlags & SCAN_DEFER_DEX) != 0); } - if ((scanFlags&SCAN_NO_DEX) == 0) { - if (performDexOptLI(pkg, null /* instruction sets */, forceDex, (scanFlags&SCAN_DEFER_DEX) != 0, false) - == DEX_OPT_FAILED) { - if ((scanFlags & SCAN_DELETE_DATA_ON_FAILURES) != 0) { - removeDataDirsLI(pkg.packageName); - } - + if ((scanFlags & SCAN_NO_DEX) == 0) { + if (performDexOptLI(pkg, null /* instruction sets */, forceDex, + (scanFlags & SCAN_DEFER_DEX) != 0, false) == DEX_OPT_FAILED) { throw new PackageManagerException(INSTALL_FAILED_DEXOPT, "scanPackageLI"); } } @@ -5676,16 +5685,11 @@ public class PackageManagerService extends IPackageManager.Stub { // if these fail, we should abort the install since installing the library will // result in some apps being broken. if (clientLibPkgs != null) { - if ((scanFlags&SCAN_NO_DEX) == 0) { - for (int i=0; i<clientLibPkgs.size(); i++) { + if ((scanFlags & SCAN_NO_DEX) == 0) { + for (int i = 0; i < clientLibPkgs.size(); i++) { PackageParser.Package clientPkg = clientLibPkgs.get(i); - if (performDexOptLI(clientPkg, null /* instruction sets */, - forceDex, (scanFlags&SCAN_DEFER_DEX) != 0, false) - == DEX_OPT_FAILED) { - if ((scanFlags & SCAN_DELETE_DATA_ON_FAILURES) != 0) { - removeDataDirsLI(pkg.packageName); - } - + if (performDexOptLI(clientPkg, null /* instruction sets */, forceDex, + (scanFlags & SCAN_DEFER_DEX) != 0, false) == DEX_OPT_FAILED) { throw new PackageManagerException(INSTALL_FAILED_DEXOPT, "scanPackageLI failed to dexopt clientLibPkgs"); } @@ -11011,45 +11015,40 @@ public class PackageManagerService extends IPackageManager.Stub { Slog.w(TAG, "Attempt to delete null packageName."); return false; } + + // Try finding details about the requested package PackageParser.Package pkg; - boolean dataOnly = false; - final int appId; synchronized (mPackages) { pkg = mPackages.get(packageName); if (pkg == null) { - dataOnly = true; - PackageSetting ps = mSettings.mPackages.get(packageName); - if ((ps == null) || (ps.pkg == null)) { - Slog.w(TAG, "Package named '" + packageName + "' doesn't exist."); - return false; - } - pkg = ps.pkg; - } - if (!dataOnly) { - // need to check this only for fully installed applications - if (pkg == null) { - Slog.w(TAG, "Package named '" + packageName + "' doesn't exist."); - return false; - } - final ApplicationInfo applicationInfo = pkg.applicationInfo; - if (applicationInfo == null) { - Slog.w(TAG, "Package " + packageName + " has no applicationInfo."); - return false; + final PackageSetting ps = mSettings.mPackages.get(packageName); + if (ps != null) { + pkg = ps.pkg; } } - if (pkg != null && pkg.applicationInfo != null) { - appId = pkg.applicationInfo.uid; - } else { - appId = -1; - } } + + if (pkg == null) { + Slog.w(TAG, "Package named '" + packageName + "' doesn't exist."); + } + + // Always delete data directories for package, even if we found no other + // record of app. This helps users recover from UID mismatches without + // resorting to a full data wipe. int retCode = mInstaller.clearUserData(packageName, userId); if (retCode < 0) { - Slog.w(TAG, "Couldn't remove cache files for package: " - + packageName); + Slog.w(TAG, "Couldn't remove cache files for package: " + packageName); return false; } - removeKeystoreDataIfNeeded(userId, appId); + + if (pkg == null) { + return false; + } + + if (pkg != null && pkg.applicationInfo != null) { + final int appId = pkg.applicationInfo.uid; + removeKeystoreDataIfNeeded(userId, appId); + } // Create a native library symlink only if we have native libraries // and if the native libraries are 32 bit libraries. We do not provide diff --git a/services/core/java/com/android/server/power/PowerManagerService.java b/services/core/java/com/android/server/power/PowerManagerService.java index 7808800..0a4b3bc 100644 --- a/services/core/java/com/android/server/power/PowerManagerService.java +++ b/services/core/java/com/android/server/power/PowerManagerService.java @@ -814,7 +814,7 @@ public final class PowerManagerService extends com.android.server.SystemService + " [" + wakeLock.mTag + "], flags=0x" + Integer.toHexString(flags)); } - if ((flags & PowerManager.WAIT_FOR_DISTANT_PROXIMITY) != 0) { + if ((flags & PowerManager.RELEASE_FLAG_WAIT_FOR_NO_PROXIMITY) != 0) { mRequestWaitForNegativeProximity = true; } diff --git a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java index e1ade63..a8245e7 100644 --- a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java +++ b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java @@ -843,7 +843,7 @@ public class WallpaperManagerService extends IWallpaperManager.Stub { } File file = new File(dir, WALLPAPER); ParcelFileDescriptor fd = ParcelFileDescriptor.open(file, - MODE_CREATE|MODE_READ_WRITE); + MODE_CREATE|MODE_READ_WRITE|MODE_TRUNCATE); if (!SELinux.restorecon(file)) { return null; } diff --git a/services/core/java/com/android/server/wm/WindowAnimator.java b/services/core/java/com/android/server/wm/WindowAnimator.java index 50e417b..da5cfda 100644 --- a/services/core/java/com/android/server/wm/WindowAnimator.java +++ b/services/core/java/com/android/server/wm/WindowAnimator.java @@ -252,6 +252,10 @@ public class WindowAnimator { final boolean showImeOverKeyguard = imeTarget != null && imeTarget.isVisibleNow() && (imeTarget.getAttrs().flags & FLAG_SHOW_WHEN_LOCKED) != 0; + final WindowState winShowWhenLocked = (WindowState) mPolicy.getWinShowWhenLockedLw(); + final AppWindowToken appShowWhenLocked = winShowWhenLocked == null ? + null : winShowWhenLocked.mAppToken; + for (int i = windows.size() - 1; i >= 0; i--) { WindowState win = windows.get(i); WindowStateAnimator winAnimator = win.mWinAnimator; @@ -316,8 +320,8 @@ public class WindowAnimator { + " hidden=" + win.mRootToken.hidden + " anim=" + win.mWinAnimator.mAnimation); } else if (mPolicy.canBeForceHidden(win, win.mAttrs)) { - final boolean hideWhenLocked = (flags & FLAG_SHOW_WHEN_LOCKED) == 0 && - !(win.mIsImWindow && showImeOverKeyguard); + final boolean hideWhenLocked = !((win.mIsImWindow && showImeOverKeyguard) || + (appShowWhenLocked != null && appShowWhenLocked == win.mAppToken)); final boolean changed; if (((mForceHiding == KEYGUARD_ANIMATING_IN) && (!winAnimator.isAnimating() || hideWhenLocked)) @@ -454,7 +458,10 @@ public class WindowAnimator { } final int color = winAnimator.mAnimation.getBackgroundColor(); if (color != 0) { - win.getStack().setAnimationBackground(winAnimator, color); + final TaskStack stack = win.getStack(); + if (stack != null) { + stack.setAnimationBackground(winAnimator, color); + } } } mAnimating = true; @@ -473,7 +480,10 @@ public class WindowAnimator { final int color = appAnimator.animation.getBackgroundColor(); if (color != 0) { - win.getStack().setAnimationBackground(winAnimator, color); + final TaskStack stack = win.getStack(); + if (stack != null) { + stack.setAnimationBackground(winAnimator, color); + } } } } // end forall windows diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index b7e56cb..9033f30 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -8556,7 +8556,8 @@ public class WindowManagerService extends IWindowManager.Stub layerChanged = true; anyLayerChanged = true; } - if (layerChanged && w.getStack().isDimming(winAnimator)) { + final TaskStack stack = w.getStack(); + if (layerChanged && stack != null && stack.isDimming(winAnimator)) { // Force an animation pass just to update the mDimLayer layer. scheduleAnimationLocked(); } @@ -9380,6 +9381,9 @@ public class WindowManagerService extends IWindowManager.Stub && !w.mExiting) { final WindowStateAnimator winAnimator = w.mWinAnimator; final TaskStack stack = w.getStack(); + if (stack == null) { + return; + } stack.setDimmingTag(); if (!stack.isDimming(winAnimator)) { if (localLOGV) Slog.v(TAG, "Win " + w + " start dimming."); diff --git a/services/core/java/com/android/server/wm/WindowStateAnimator.java b/services/core/java/com/android/server/wm/WindowStateAnimator.java index dd611ce..da97876 100644 --- a/services/core/java/com/android/server/wm/WindowStateAnimator.java +++ b/services/core/java/com/android/server/wm/WindowStateAnimator.java @@ -1368,7 +1368,10 @@ class WindowStateAnimator { mAnimator.setPendingLayoutChanges(w.getDisplayId(), WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER); if ((w.mAttrs.flags & LayoutParams.FLAG_DIM_BEHIND) != 0) { - w.getStack().startDimmingIfNeeded(this); + final TaskStack stack = w.getStack(); + if (stack != null) { + stack.startDimmingIfNeeded(this); + } } } catch (RuntimeException e) { // If something goes wrong with the surface (such diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java index 8e82e2a..efaf253 100644 --- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java @@ -19,6 +19,7 @@ package com.android.server.devicepolicy; import static android.Manifest.permission.MANAGE_CA_CERTIFICATES; import android.accessibilityservice.AccessibilityServiceInfo; +import android.accounts.AccountManager; import android.app.Activity; import android.app.ActivityManagerNative; import android.app.AlarmManager; @@ -3579,7 +3580,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { + " for device owner"); } synchronized (this) { - if (isDeviceProvisioned()) { + if (!allowedToSetDeviceOwnerOnDevice()) { throw new IllegalStateException( "Trying to set device owner but device is already provisioned."); } @@ -3878,9 +3879,18 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { return null; } - private boolean isDeviceProvisioned() { - return Settings.Global.getInt(mContext.getContentResolver(), - Settings.Global.DEVICE_PROVISIONED, 0) > 0; + /** + * Device owner can only be set on an unprovisioned device, unless it was initiated by "adb", in + * which case we allow it if no account is associated with the device. + */ + private boolean allowedToSetDeviceOwnerOnDevice() { + int callingId = Binder.getCallingUid(); + if (callingId == Process.SHELL_UID || callingId == Process.ROOT_UID) { + return AccountManager.get(mContext).getAccounts().length == 0; + } else { + return Settings.Global.getInt(mContext.getContentResolver(), + Settings.Global.DEVICE_PROVISIONED, 0) == 0; + } } private boolean isUserSetupComplete(int userId) { diff --git a/services/usage/java/com/android/server/usage/UsageStatsDatabase.java b/services/usage/java/com/android/server/usage/UsageStatsDatabase.java index 62a7ec0..972c929 100644 --- a/services/usage/java/com/android/server/usage/UsageStatsDatabase.java +++ b/services/usage/java/com/android/server/usage/UsageStatsDatabase.java @@ -61,7 +61,7 @@ class UsageStatsDatabase { /** * Initialize any directories required and index what stats are available. */ - void init() { + public void init(long currentTimeMillis) { synchronized (mLock) { for (File f : mIntervalDirs) { f.mkdirs(); @@ -72,27 +72,53 @@ class UsageStatsDatabase { } checkVersionLocked(); + indexFilesLocked(); - final FilenameFilter backupFileFilter = new FilenameFilter() { - @Override - public boolean accept(File dir, String name) { - return !name.endsWith(".bak"); + // Delete files that are in the future. + for (TimeSparseArray<AtomicFile> files : mSortedStatFiles) { + final int startIndex = files.closestIndexOnOrAfter(currentTimeMillis); + if (startIndex < 0) { + continue; } - }; - // Index the available usage stat files on disk. - for (int i = 0; i < mSortedStatFiles.length; i++) { + final int fileCount = files.size(); + for (int i = startIndex; i < fileCount; i++) { + files.valueAt(i).delete(); + } + + // Remove in a separate loop because any accesses (valueAt) + // will cause a gc in the SparseArray and mess up the order. + for (int i = startIndex; i < fileCount; i++) { + files.removeAt(i); + } + } + } + } + + private void indexFilesLocked() { + final FilenameFilter backupFileFilter = new FilenameFilter() { + @Override + public boolean accept(File dir, String name) { + return !name.endsWith(".bak"); + } + }; + + // Index the available usage stat files on disk. + for (int i = 0; i < mSortedStatFiles.length; i++) { + if (mSortedStatFiles[i] == null) { mSortedStatFiles[i] = new TimeSparseArray<>(); - File[] files = mIntervalDirs[i].listFiles(backupFileFilter); - if (files != null) { - if (DEBUG) { - Slog.d(TAG, "Found " + files.length + " stat files for interval " + i); - } + } else { + mSortedStatFiles[i].clear(); + } + File[] files = mIntervalDirs[i].listFiles(backupFileFilter); + if (files != null) { + if (DEBUG) { + Slog.d(TAG, "Found " + files.length + " stat files for interval " + i); + } - for (File f : files) { - final AtomicFile af = new AtomicFile(f); - mSortedStatFiles[i].put(UsageStatsXml.parseBeginTime(af), af); - } + for (File f : files) { + final AtomicFile af = new AtomicFile(f); + mSortedStatFiles[i].put(UsageStatsXml.parseBeginTime(af), af); } } } @@ -135,6 +161,38 @@ class UsageStatsDatabase { } } + public void onTimeChanged(long timeDiffMillis) { + synchronized (mLock) { + for (TimeSparseArray<AtomicFile> files : mSortedStatFiles) { + final int fileCount = files.size(); + for (int i = 0; i < fileCount; i++) { + final AtomicFile file = files.valueAt(i); + final long newTime = files.keyAt(i) + timeDiffMillis; + if (newTime < 0) { + Slog.i(TAG, "Deleting file " + file.getBaseFile().getAbsolutePath() + + " for it is in the future now."); + file.delete(); + } else { + try { + file.openRead().close(); + } catch (IOException e) { + // Ignore, this is just to make sure there are no backups. + } + final File newFile = new File(file.getBaseFile().getParentFile(), + Long.toString(newTime)); + Slog.i(TAG, "Moving file " + file.getBaseFile().getAbsolutePath() + " to " + + newFile.getAbsolutePath()); + file.getBaseFile().renameTo(newFile); + } + } + files.clear(); + } + + // Now re-index the new files. + indexFilesLocked(); + } + } + /** * Get the latest stats that exist for this interval type. */ @@ -296,25 +354,24 @@ class UsageStatsDatabase { /** * Remove any usage stat files that are too old. */ - public void prune() { + public void prune(final long currentTimeMillis) { synchronized (mLock) { - long timeNow = System.currentTimeMillis(); - mCal.setTimeInMillis(timeNow); + mCal.setTimeInMillis(currentTimeMillis); mCal.addYears(-3); pruneFilesOlderThan(mIntervalDirs[UsageStatsManager.INTERVAL_YEARLY], mCal.getTimeInMillis()); - mCal.setTimeInMillis(timeNow); + mCal.setTimeInMillis(currentTimeMillis); mCal.addMonths(-6); pruneFilesOlderThan(mIntervalDirs[UsageStatsManager.INTERVAL_MONTHLY], mCal.getTimeInMillis()); - mCal.setTimeInMillis(timeNow); + mCal.setTimeInMillis(currentTimeMillis); mCal.addWeeks(-4); pruneFilesOlderThan(mIntervalDirs[UsageStatsManager.INTERVAL_WEEKLY], mCal.getTimeInMillis()); - mCal.setTimeInMillis(timeNow); + mCal.setTimeInMillis(currentTimeMillis); mCal.addDays(-7); pruneFilesOlderThan(mIntervalDirs[UsageStatsManager.INTERVAL_DAILY], mCal.getTimeInMillis()); diff --git a/services/usage/java/com/android/server/usage/UsageStatsService.java b/services/usage/java/com/android/server/usage/UsageStatsService.java index 92117c3..2ed9745 100644 --- a/services/usage/java/com/android/server/usage/UsageStatsService.java +++ b/services/usage/java/com/android/server/usage/UsageStatsService.java @@ -65,6 +65,7 @@ public class UsageStatsService extends SystemService implements private static final long TEN_SECONDS = 10 * 1000; private static final long TWENTY_MINUTES = 20 * 60 * 1000; private static final long FLUSH_INTERVAL = DEBUG ? TEN_SECONDS : TWENTY_MINUTES; + private static final long TIME_CHANGE_THRESHOLD_MILLIS = 2 * 1000; // Two seconds. // Handler message types. static final int MSG_REPORT_EVENT = 0; @@ -171,18 +172,47 @@ public class UsageStatsService extends SystemService implements } } - private UserUsageStatsService getUserDataAndInitializeIfNeededLocked(int userId) { + private UserUsageStatsService getUserDataAndInitializeIfNeededLocked(int userId, + long currentTimeMillis) { UserUsageStatsService service = mUserState.get(userId); if (service == null) { service = new UserUsageStatsService(userId, new File(mUsageStatsDir, Integer.toString(userId)), this); - service.init(); + service.init(currentTimeMillis); mUserState.put(userId, service); } return service; } /** + * This should be the only way to get the time from the system. + */ + private long checkAndGetTimeLocked() { + final long actualSystemTime = System.currentTimeMillis(); + final long actualRealtime = SystemClock.elapsedRealtime(); + final long expectedSystemTime = (actualRealtime - mRealTimeSnapshot) + mSystemTimeSnapshot; + if (Math.abs(actualSystemTime - expectedSystemTime) > TIME_CHANGE_THRESHOLD_MILLIS) { + // The time has changed. + final int userCount = mUserState.size(); + for (int i = 0; i < userCount; i++) { + final UserUsageStatsService service = mUserState.valueAt(i); + service.onTimeChanged(expectedSystemTime, actualSystemTime); + } + mRealTimeSnapshot = actualRealtime; + mSystemTimeSnapshot = actualSystemTime; + } + return actualSystemTime; + } + + /** + * Assuming the event's timestamp is measured in milliseconds since boot, + * convert it to a system wall time. + */ + private void convertToSystemTimeLocked(UsageEvents.Event event) { + event.mTimeStamp = Math.max(0, event.mTimeStamp - mRealTimeSnapshot) + mSystemTimeSnapshot; + } + + /** * Called by the Binder stub */ void shutdown() { @@ -197,7 +227,11 @@ public class UsageStatsService extends SystemService implements */ void reportEvent(UsageEvents.Event event, int userId) { synchronized (mLock) { - final UserUsageStatsService service = getUserDataAndInitializeIfNeededLocked(userId); + final long timeNow = checkAndGetTimeLocked(); + convertToSystemTimeLocked(event); + + final UserUsageStatsService service = + getUserDataAndInitializeIfNeededLocked(userId, timeNow); service.reportEvent(event); } } @@ -226,12 +260,14 @@ public class UsageStatsService extends SystemService implements * Called by the Binder stub. */ List<UsageStats> queryUsageStats(int userId, int bucketType, long beginTime, long endTime) { - if (!validRange(beginTime, endTime)) { - return null; - } - synchronized (mLock) { - UserUsageStatsService service = getUserDataAndInitializeIfNeededLocked(userId); + final long timeNow = checkAndGetTimeLocked(); + if (!validRange(timeNow, beginTime, endTime)) { + return null; + } + + final UserUsageStatsService service = + getUserDataAndInitializeIfNeededLocked(userId, timeNow); return service.queryUsageStats(bucketType, beginTime, endTime); } } @@ -241,12 +277,14 @@ public class UsageStatsService extends SystemService implements */ List<ConfigurationStats> queryConfigurationStats(int userId, int bucketType, long beginTime, long endTime) { - if (!validRange(beginTime, endTime)) { - return null; - } - synchronized (mLock) { - UserUsageStatsService service = getUserDataAndInitializeIfNeededLocked(userId); + final long timeNow = checkAndGetTimeLocked(); + if (!validRange(timeNow, beginTime, endTime)) { + return null; + } + + final UserUsageStatsService service = + getUserDataAndInitializeIfNeededLocked(userId, timeNow); return service.queryConfigurationStats(bucketType, beginTime, endTime); } } @@ -255,19 +293,20 @@ public class UsageStatsService extends SystemService implements * Called by the Binder stub. */ UsageEvents queryEvents(int userId, long beginTime, long endTime) { - if (!validRange(beginTime, endTime)) { - return null; - } - synchronized (mLock) { - UserUsageStatsService service = getUserDataAndInitializeIfNeededLocked(userId); + final long timeNow = checkAndGetTimeLocked(); + if (!validRange(timeNow, beginTime, endTime)) { + return null; + } + + final UserUsageStatsService service = + getUserDataAndInitializeIfNeededLocked(userId, timeNow); return service.queryEvents(beginTime, endTime); } } - private static boolean validRange(long beginTime, long endTime) { - final long timeNow = System.currentTimeMillis(); - return beginTime <= timeNow && beginTime < endTime; + private static boolean validRange(long currentTime, long beginTime, long endTime) { + return beginTime <= currentTime && beginTime < endTime; } private void flushToDiskLocked() { @@ -387,14 +426,6 @@ public class UsageStatsService extends SystemService implements */ private class LocalService extends UsageStatsManagerInternal { - /** - * The system may have its time change, so at least make sure the events - * are monotonic in order. - */ - private long computeMonotonicSystemTime(long realTime) { - return (realTime - mRealTimeSnapshot) + mSystemTimeSnapshot; - } - @Override public void reportEvent(ComponentName component, int userId, int eventType) { if (component == null) { @@ -405,7 +436,10 @@ public class UsageStatsService extends SystemService implements UsageEvents.Event event = new UsageEvents.Event(); event.mPackage = component.getPackageName(); event.mClass = component.getClassName(); - event.mTimeStamp = computeMonotonicSystemTime(SystemClock.elapsedRealtime()); + + // This will later be converted to system time. + event.mTimeStamp = SystemClock.elapsedRealtime(); + event.mEventType = eventType; mHandler.obtainMessage(MSG_REPORT_EVENT, userId, 0, event).sendToTarget(); } @@ -419,7 +453,10 @@ public class UsageStatsService extends SystemService implements UsageEvents.Event event = new UsageEvents.Event(); event.mPackage = "android"; - event.mTimeStamp = computeMonotonicSystemTime(SystemClock.elapsedRealtime()); + + // This will later be converted to system time. + event.mTimeStamp = SystemClock.elapsedRealtime(); + event.mEventType = UsageEvents.Event.CONFIGURATION_CHANGE; event.mConfiguration = new Configuration(config); mHandler.obtainMessage(MSG_REPORT_EVENT, userId, 0, event).sendToTarget(); diff --git a/services/usage/java/com/android/server/usage/UserUsageStatsService.java b/services/usage/java/com/android/server/usage/UserUsageStatsService.java index 2769666..4916ec2 100644 --- a/services/usage/java/com/android/server/usage/UserUsageStatsService.java +++ b/services/usage/java/com/android/server/usage/UserUsageStatsService.java @@ -22,6 +22,7 @@ import android.app.usage.UsageEvents; import android.app.usage.UsageStats; import android.app.usage.UsageStatsManager; import android.content.res.Configuration; +import android.os.SystemClock; import android.util.ArraySet; import android.util.Slog; @@ -62,10 +63,9 @@ class UserUsageStatsService { mLogPrefix = "User[" + Integer.toString(userId) + "] "; } - void init() { - mDatabase.init(); + void init(final long currentTimeMillis) { + mDatabase.init(currentTimeMillis); - final long timeNow = System.currentTimeMillis(); int nullCount = 0; for (int i = 0; i < mCurrentStats.length; i++) { mCurrentStats[i] = mDatabase.getLatestUsageStats(i); @@ -73,11 +73,6 @@ class UserUsageStatsService { // Find out how many intervals we don't have data for. // Ideally it should be all or none. nullCount++; - } else if (mCurrentStats[i].beginTime > timeNow) { - Slog.e(TAG, mLogPrefix + "Interval " + i + " has stat in the future " + - mCurrentStats[i].beginTime); - mCurrentStats[i] = null; - nullCount++; } } @@ -92,7 +87,7 @@ class UserUsageStatsService { // By calling loadActiveStats, we will // generate new stats for each bucket. - loadActiveStats(); + loadActiveStats(currentTimeMillis, false); } else { // Set up the expiry date to be one day from the latest daily stat. // This may actually be today and we will rollover on the first event @@ -123,6 +118,12 @@ class UserUsageStatsService { } } + void onTimeChanged(long oldTime, long newTime) { + persistActiveStats(); + mDatabase.onTimeChanged(newTime - oldTime); + loadActiveStats(newTime, true); + } + void reportEvent(UsageEvents.Event event) { if (DEBUG) { Slog.d(TAG, mLogPrefix + "Got usage event for " + event.mPackage @@ -132,7 +133,7 @@ class UserUsageStatsService { if (event.mTimeStamp >= mDailyExpiryDate.getTimeInMillis()) { // Need to rollover - rolloverStats(); + rolloverStats(event.mTimeStamp); } final IntervalStats currentDailyStats = mCurrentStats[UsageStatsManager.INTERVAL_DAILY]; @@ -330,8 +331,8 @@ class UserUsageStatsService { } } - private void rolloverStats() { - final long startTime = System.currentTimeMillis(); + private void rolloverStats(final long currentTimeMillis) { + final long startTime = SystemClock.elapsedRealtime(); Slog.i(TAG, mLogPrefix + "Rolling over usage stats"); // Finish any ongoing events with an END_OF_DAY event. Make a note of which components @@ -348,7 +349,7 @@ class UserUsageStatsService { continuePreviousDay.add(pkgStats.mPackageName); stat.update(pkgStats.mPackageName, mDailyExpiryDate.getTimeInMillis() - 1, UsageEvents.Event.END_OF_DAY); - mStatsChanged = true; + notifyStatsChanged(); } } @@ -356,8 +357,8 @@ class UserUsageStatsService { } persistActiveStats(); - mDatabase.prune(); - loadActiveStats(); + mDatabase.prune(currentTimeMillis); + loadActiveStats(currentTimeMillis, false); final int continueCount = continuePreviousDay.size(); for (int i = 0; i < continueCount; i++) { @@ -366,12 +367,12 @@ class UserUsageStatsService { for (IntervalStats stat : mCurrentStats) { stat.update(name, beginTime, UsageEvents.Event.CONTINUE_PREVIOUS_DAY); stat.updateConfigurationStats(previousConfig, beginTime); - mStatsChanged = true; + notifyStatsChanged(); } } persistActiveStats(); - final long totalTime = System.currentTimeMillis() - startTime; + final long totalTime = SystemClock.elapsedRealtime() - startTime; Slog.i(TAG, mLogPrefix + "Rolling over usage stats complete. Took " + totalTime + " milliseconds"); } @@ -383,15 +384,16 @@ class UserUsageStatsService { } } - private void loadActiveStats() { - final long timeNow = System.currentTimeMillis(); - + /** + * @param force To force all in-memory stats to be reloaded. + */ + private void loadActiveStats(final long currentTimeMillis, boolean force) { final UnixCalendar tempCal = mDailyExpiryDate; for (int intervalType = 0; intervalType < mCurrentStats.length; intervalType++) { - tempCal.setTimeInMillis(timeNow); + tempCal.setTimeInMillis(currentTimeMillis); UnixCalendar.truncateTo(tempCal, intervalType); - if (mCurrentStats[intervalType] != null && + if (!force && mCurrentStats[intervalType] != null && mCurrentStats[intervalType].beginTime == tempCal.getTimeInMillis()) { // These are the same, no need to load them (in memory stats are always newer // than persisted stats). @@ -399,11 +401,7 @@ class UserUsageStatsService { } final long lastBeginTime = mDatabase.getLatestUsageStatsBeginTime(intervalType); - if (lastBeginTime > timeNow) { - Slog.e(TAG, mLogPrefix + "Latest usage stats for interval " + - intervalType + " begins in the future"); - mCurrentStats[intervalType] = null; - } else if (lastBeginTime >= tempCal.getTimeInMillis()) { + if (lastBeginTime >= tempCal.getTimeInMillis()) { if (DEBUG) { Slog.d(TAG, mLogPrefix + "Loading existing stats @ " + sDateFormat.format(lastBeginTime) + "(" + lastBeginTime + @@ -423,11 +421,11 @@ class UserUsageStatsService { } mCurrentStats[intervalType] = new IntervalStats(); mCurrentStats[intervalType].beginTime = tempCal.getTimeInMillis(); - mCurrentStats[intervalType].endTime = timeNow; + mCurrentStats[intervalType].endTime = currentTimeMillis; } } mStatsChanged = false; - mDailyExpiryDate.setTimeInMillis(timeNow); + mDailyExpiryDate.setTimeInMillis(currentTimeMillis); mDailyExpiryDate.addDays(1); mDailyExpiryDate.truncateToDay(); Slog.i(TAG, mLogPrefix + "Rollover scheduled @ " + diff --git a/telecomm/java/android/telecomm/Connection.java b/telecomm/java/android/telecomm/Connection.java index 729686d..2f25dcf 100644 --- a/telecomm/java/android/telecomm/Connection.java +++ b/telecomm/java/android/telecomm/Connection.java @@ -68,13 +68,13 @@ public abstract class Connection { /** @hide */ public abstract static class Listener { public void onStateChanged(Connection c, int state) {} - public void onHandleChanged(Connection c, Uri newHandle, int presentation) {} + public void onAddressChanged(Connection c, Uri newAddress, int presentation) {} public void onCallerDisplayNameChanged( Connection c, String callerDisplayName, int presentation) {} public void onVideoStateChanged(Connection c, int videoState) {} public void onDisconnected(Connection c, int cause, String message) {} public void onPostDialWait(Connection c, String remaining) {} - public void onRequestingRingback(Connection c, boolean ringback) {} + public void onRingbackRequested(Connection c, boolean ringback) {} public void onDestroyed(Connection c) {} public void onCallCapabilitiesChanged(Connection c, int callCapabilities) {} public void onVideoProviderChanged( @@ -464,11 +464,11 @@ public abstract class Connection { private int mState = STATE_NEW; private AudioState mAudioState; - private Uri mHandle; - private int mHandlePresentation; + private Uri mAddress; + private int mAddressPresentation; private String mCallerDisplayName; private int mCallerDisplayNamePresentation; - private boolean mRequestingRingback = false; + private boolean mRingbackRequested = false; private int mCallCapabilities; private VideoProvider mVideoProvider; private boolean mAudioModeIsVoip; @@ -485,18 +485,18 @@ public abstract class Connection { public Connection() {} /** - * @return The handle (e.g., phone number) to which this Connection is currently communicating. + * @return The address (e.g., phone number) to which this Connection is currently communicating. */ - public final Uri getHandle() { - return mHandle; + public final Uri getAddress() { + return mAddress; } /** - * @return The presentation requirements for the handle. + * @return The presentation requirements for the address. * See {@link TelecommManager} for valid values. */ - public final int getHandlePresentation() { - return mHandlePresentation; + public final int getAddressPresentation() { + return mAddressPresentation; } /** @@ -556,8 +556,8 @@ public abstract class Connection { * Returns whether this connection is requesting that the system play a ringback tone * on its behalf. */ - public final boolean isRequestingRingback() { - return mRequestingRingback; + public final boolean isRingbackRequested() { + return mRingbackRequested; } /** @@ -662,18 +662,18 @@ public abstract class Connection { } /** - * Sets the value of the {@link #getHandle()} property. + * Sets the value of the {@link #getAddress()} property. * - * @param handle The new handle. - * @param presentation The presentation requirements for the handle. + * @param address The new address. + * @param presentation The presentation requirements for the address. * See {@link TelecommManager} for valid values. */ - public final void setHandle(Uri handle, int presentation) { - Log.d(this, "setHandle %s", handle); - mHandle = handle; - mHandlePresentation = presentation; + public final void setAddress(Uri address, int presentation) { + Log.d(this, "setAddress %s", address); + mAddress = address; + mAddressPresentation = presentation; for (Listener l : mListeners) { - l.onHandleChanged(this, handle, presentation); + l.onAddressChanged(this, address, presentation); } } @@ -716,7 +716,7 @@ public abstract class Connection { * communicate). */ public final void setActive() { - setRequestingRingback(false); + setRingbackRequested(false); setState(STATE_ACTIVE); } @@ -804,11 +804,11 @@ public abstract class Connection { * * @param ringback Whether the ringback tone is to be played. */ - public final void setRequestingRingback(boolean ringback) { - if (mRequestingRingback != ringback) { - mRequestingRingback = ringback; + public final void setRingbackRequested(boolean ringback) { + if (mRingbackRequested != ringback) { + mRingbackRequested = ringback; for (Listener l : mListeners) { - l.onRequestingRingback(this, ringback); + l.onRingbackRequested(this, ringback); } } } diff --git a/telecomm/java/android/telecomm/ConnectionService.java b/telecomm/java/android/telecomm/ConnectionService.java index 76e208b..05ddc27 100644 --- a/telecomm/java/android/telecomm/ConnectionService.java +++ b/telecomm/java/android/telecomm/ConnectionService.java @@ -414,9 +414,9 @@ public abstract class ConnectionService extends Service { } @Override - public void onHandleChanged(Connection c, Uri handle, int presentation) { + public void onAddressChanged(Connection c, Uri address, int presentation) { String id = mIdByConnection.get(c); - mAdapter.setHandle(id, handle, presentation); + mAdapter.setAddress(id, address, presentation); } @Override @@ -439,10 +439,10 @@ public abstract class ConnectionService extends Service { } @Override - public void onRequestingRingback(Connection c, boolean ringback) { + public void onRingbackRequested(Connection c, boolean ringback) { String id = mIdByConnection.get(c); Log.d(this, "Adapter onRingback %b", ringback); - mAdapter.setRequestingRingback(id, ringback); + mAdapter.setRingbackRequested(id, ringback); } @Override @@ -462,7 +462,7 @@ public abstract class ConnectionService extends Service { @Override public void onAudioModeIsVoipChanged(Connection c, boolean isVoip) { String id = mIdByConnection.get(c); - mAdapter.setAudioModeIsVoip(id, isVoip); + mAdapter.setIsVoipAudioMode(id, isVoip); } @Override @@ -498,6 +498,13 @@ public abstract class ConnectionService extends Service { return mBinder; } + /** {@inheritDoc} */ + @Override + public boolean onUnbind(Intent intent) { + endAllConnections(); + return super.onUnbind(intent); + } + /** * This can be used by telecomm to either create a new outgoing call or attach to an existing * incoming call. In either case, telecomm will cycle through a set of services and call @@ -523,8 +530,8 @@ public abstract class ConnectionService extends Service { addConnection(callId, connection); } - Uri handle = connection.getHandle(); - String number = handle == null ? "null" : handle.getSchemeSpecificPart(); + Uri address = connection.getAddress(); + String number = address == null ? "null" : address.getSchemeSpecificPart(); Log.v(this, "createConnection, number: %s, state: %s, capabilities: %s", Connection.toLogSafePhoneNumber(number), Connection.stateToString(connection.getState()), @@ -538,14 +545,14 @@ public abstract class ConnectionService extends Service { request.getAccountHandle(), connection.getState(), connection.getCallCapabilities(), - connection.getHandle(), - connection.getHandlePresentation(), + connection.getAddress(), + connection.getAddressPresentation(), connection.getCallerDisplayName(), connection.getCallerDisplayNamePresentation(), connection.getVideoProvider() == null ? null : connection.getVideoProvider().getInterface(), connection.getVideoState(), - connection.isRequestingRingback(), + connection.isRingbackRequested(), connection.getAudioModeIsVoip(), connection.getStatusHints(), connection.getDisconnectCause(), @@ -951,4 +958,17 @@ public abstract class ConnectionService extends Service { } return sNullConference; } + + private void endAllConnections() { + // Unbound from telecomm. We should end all connections and conferences. + for (Connection connection : mIdByConnection.keySet()) { + // only operate on top-level calls. Conference calls will be removed on their own. + if (connection.getConference() == null) { + connection.onDisconnect(); + } + } + for (Conference conference : mIdByConference.keySet()) { + conference.onDisconnect(); + } + } } diff --git a/telecomm/java/android/telecomm/ConnectionServiceAdapter.java b/telecomm/java/android/telecomm/ConnectionServiceAdapter.java index e3dc713..19f42d6 100644 --- a/telecomm/java/android/telecomm/ConnectionServiceAdapter.java +++ b/telecomm/java/android/telecomm/ConnectionServiceAdapter.java @@ -168,10 +168,10 @@ final class ConnectionServiceAdapter implements DeathRecipient { * @param callId The unique ID of the call whose ringback is being changed. * @param ringback Whether Telecomm should start playing a ringback tone. */ - void setRequestingRingback(String callId, boolean ringback) { + void setRingbackRequested(String callId, boolean ringback) { for (IConnectionServiceAdapter adapter : mAdapters) { try { - adapter.setRequestingRingback(callId, ringback); + adapter.setRingbackRequested(callId, ringback); } catch (RemoteException e) { } } @@ -280,10 +280,10 @@ final class ConnectionServiceAdapter implements DeathRecipient { * @param callId The unique ID of the call to set with the given call video provider. * @param isVoip True if the audio mode is VOIP. */ - void setAudioModeIsVoip(String callId, boolean isVoip) { + void setIsVoipAudioMode(String callId, boolean isVoip) { for (IConnectionServiceAdapter adapter : mAdapters) { try { - adapter.setAudioModeIsVoip(callId, isVoip); + adapter.setIsVoipAudioMode(callId, isVoip); } catch (RemoteException e) { } } @@ -298,10 +298,10 @@ final class ConnectionServiceAdapter implements DeathRecipient { } } - void setHandle(String callId, Uri handle, int presentation) { + void setAddress(String callId, Uri address, int presentation) { for (IConnectionServiceAdapter adapter : mAdapters) { try { - adapter.setHandle(callId, handle, presentation); + adapter.setAddress(callId, address, presentation); } catch (RemoteException e) { } } diff --git a/telecomm/java/android/telecomm/ConnectionServiceAdapterServant.java b/telecomm/java/android/telecomm/ConnectionServiceAdapterServant.java index 21e99db..2aac7fc 100644 --- a/telecomm/java/android/telecomm/ConnectionServiceAdapterServant.java +++ b/telecomm/java/android/telecomm/ConnectionServiceAdapterServant.java @@ -44,7 +44,7 @@ final class ConnectionServiceAdapterServant { private static final int MSG_SET_DIALING = 4; private static final int MSG_SET_DISCONNECTED = 5; private static final int MSG_SET_ON_HOLD = 6; - private static final int MSG_SET_REQUESTING_RINGBACK = 7; + private static final int MSG_SET_RINGBACK_REQUESTED = 7; private static final int MSG_SET_CALL_CAPABILITIES = 8; private static final int MSG_SET_IS_CONFERENCED = 9; private static final int MSG_ADD_CONFERENCE_CALL = 10; @@ -53,9 +53,9 @@ final class ConnectionServiceAdapterServant { private static final int MSG_QUERY_REMOTE_CALL_SERVICES = 13; private static final int MSG_SET_VIDEO_STATE = 14; private static final int MSG_SET_VIDEO_CALL_PROVIDER = 15; - private static final int MSG_SET_AUDIO_MODE_IS_VOIP = 16; + private static final int MSG_SET_IS_VOIP_AUDIO_MODE = 16; private static final int MSG_SET_STATUS_HINTS = 17; - private static final int MSG_SET_HANDLE = 18; + private static final int MSG_SET_ADDRESS = 18; private static final int MSG_SET_CALLER_DISPLAY_NAME = 19; private static final int MSG_SET_CONFERENCEABLE_CONNECTIONS = 20; @@ -107,8 +107,8 @@ final class ConnectionServiceAdapterServant { case MSG_SET_ON_HOLD: mDelegate.setOnHold((String) msg.obj); break; - case MSG_SET_REQUESTING_RINGBACK: - mDelegate.setRequestingRingback((String) msg.obj, msg.arg1 == 1); + case MSG_SET_RINGBACK_REQUESTED: + mDelegate.setRingbackRequested((String) msg.obj, msg.arg1 == 1); break; case MSG_SET_CALL_CAPABILITIES: mDelegate.setCallCapabilities((String) msg.obj, msg.arg1); @@ -160,8 +160,8 @@ final class ConnectionServiceAdapterServant { } break; } - case MSG_SET_AUDIO_MODE_IS_VOIP: - mDelegate.setAudioModeIsVoip((String) msg.obj, msg.arg1 == 1); + case MSG_SET_IS_VOIP_AUDIO_MODE: + mDelegate.setIsVoipAudioMode((String) msg.obj, msg.arg1 == 1); break; case MSG_SET_STATUS_HINTS: { SomeArgs args = (SomeArgs) msg.obj; @@ -172,10 +172,10 @@ final class ConnectionServiceAdapterServant { } break; } - case MSG_SET_HANDLE: { + case MSG_SET_ADDRESS: { SomeArgs args = (SomeArgs) msg.obj; try { - mDelegate.setHandle((String) args.arg1, (Uri) args.arg2, args.argi1); + mDelegate.setAddress((String) args.arg1, (Uri) args.arg2, args.argi1); } finally { args.recycle(); } @@ -249,8 +249,8 @@ final class ConnectionServiceAdapterServant { } @Override - public void setRequestingRingback(String connectionId, boolean ringback) { - mHandler.obtainMessage(MSG_SET_REQUESTING_RINGBACK, ringback ? 1 : 0, 0, connectionId) + public void setRingbackRequested(String connectionId, boolean ringback) { + mHandler.obtainMessage(MSG_SET_RINGBACK_REQUESTED, ringback ? 1 : 0, 0, connectionId) .sendToTarget(); } @@ -308,8 +308,8 @@ final class ConnectionServiceAdapterServant { } @Override - public final void setAudioModeIsVoip(String connectionId, boolean isVoip) { - mHandler.obtainMessage(MSG_SET_AUDIO_MODE_IS_VOIP, isVoip ? 1 : 0, 0, + public final void setIsVoipAudioMode(String connectionId, boolean isVoip) { + mHandler.obtainMessage(MSG_SET_IS_VOIP_AUDIO_MODE, isVoip ? 1 : 0, 0, connectionId).sendToTarget(); } @@ -322,12 +322,12 @@ final class ConnectionServiceAdapterServant { } @Override - public final void setHandle(String connectionId, Uri handle, int presentation) { + public final void setAddress(String connectionId, Uri address, int presentation) { SomeArgs args = SomeArgs.obtain(); args.arg1 = connectionId; - args.arg2 = handle; + args.arg2 = address; args.argi1 = presentation; - mHandler.obtainMessage(MSG_SET_HANDLE, args).sendToTarget(); + mHandler.obtainMessage(MSG_SET_ADDRESS, args).sendToTarget(); } @Override diff --git a/telecomm/java/android/telecomm/ParcelableConnection.java b/telecomm/java/android/telecomm/ParcelableConnection.java index 2e21d37..cadcd85 100644 --- a/telecomm/java/android/telecomm/ParcelableConnection.java +++ b/telecomm/java/android/telecomm/ParcelableConnection.java @@ -35,14 +35,14 @@ public final class ParcelableConnection implements Parcelable { private final PhoneAccountHandle mPhoneAccount; private final int mState; private final int mCapabilities; - private final Uri mHandle; - private final int mHandlePresentation; + private final Uri mAddress; + private final int mAddressPresentation; private final String mCallerDisplayName; private final int mCallerDisplayNamePresentation; private final IVideoProvider mVideoProvider; private final int mVideoState; - private final boolean mRequestingRingback; - private final boolean mAudioModeIsVoip; + private final boolean mRingbackRequested; + private final boolean mIsVoipAudioMode; private final StatusHints mStatusHints; private final int mDisconnectCause; private final String mDisconnectMessage; @@ -53,14 +53,14 @@ public final class ParcelableConnection implements Parcelable { PhoneAccountHandle phoneAccount, int state, int capabilities, - Uri handle, - int handlePresentation, + Uri address, + int addressPresentation, String callerDisplayName, int callerDisplayNamePresentation, IVideoProvider videoProvider, int videoState, - boolean requestingRingback, - boolean audioModeIsVoip, + boolean ringbackRequested, + boolean isVoipAudioMode, StatusHints statusHints, int disconnectCause, String disconnectMessage, @@ -68,14 +68,14 @@ public final class ParcelableConnection implements Parcelable { mPhoneAccount = phoneAccount; mState = state; mCapabilities = capabilities; - mHandle = handle; - mHandlePresentation = handlePresentation; + mAddress = address; + mAddressPresentation = addressPresentation; mCallerDisplayName = callerDisplayName; mCallerDisplayNamePresentation = callerDisplayNamePresentation; mVideoProvider = videoProvider; mVideoState = videoState; - mRequestingRingback = requestingRingback; - mAudioModeIsVoip = audioModeIsVoip; + mRingbackRequested = ringbackRequested; + mIsVoipAudioMode = isVoipAudioMode; mStatusHints = statusHints; mDisconnectCause = disconnectCause; mDisconnectMessage = disconnectMessage; @@ -96,11 +96,11 @@ public final class ParcelableConnection implements Parcelable { } public Uri getHandle() { - return mHandle; + return mAddress; } public int getHandlePresentation() { - return mHandlePresentation; + return mAddressPresentation; } public String getCallerDisplayName() { @@ -119,12 +119,12 @@ public final class ParcelableConnection implements Parcelable { return mVideoState; } - public boolean isRequestingRingback() { - return mRequestingRingback; + public boolean isRingbackRequested() { + return mRingbackRequested; } - public boolean getAudioModeIsVoip() { - return mAudioModeIsVoip; + public boolean getIsVoipAudioMode() { + return mIsVoipAudioMode; } public final StatusHints getStatusHints() { @@ -164,14 +164,14 @@ public final class ParcelableConnection implements Parcelable { PhoneAccountHandle phoneAccount = source.readParcelable(classLoader); int state = source.readInt(); int capabilities = source.readInt(); - Uri handle = source.readParcelable(classLoader); - int handlePresentation = source.readInt(); + Uri address = source.readParcelable(classLoader); + int addressPresentation = source.readInt(); String callerDisplayName = source.readString(); int callerDisplayNamePresentation = source.readInt(); IVideoProvider videoCallProvider = IVideoProvider.Stub.asInterface(source.readStrongBinder()); int videoState = source.readInt(); - boolean requestingRingback = source.readByte() == 1; + boolean ringbackRequested = source.readByte() == 1; boolean audioModeIsVoip = source.readByte() == 1; StatusHints statusHints = source.readParcelable(classLoader); int disconnectCauseCode = source.readInt(); @@ -183,13 +183,13 @@ public final class ParcelableConnection implements Parcelable { phoneAccount, state, capabilities, - handle, - handlePresentation, + address, + addressPresentation, callerDisplayName, callerDisplayNamePresentation, videoCallProvider, videoState, - requestingRingback, + ringbackRequested, audioModeIsVoip, statusHints, disconnectCauseCode, @@ -215,15 +215,15 @@ public final class ParcelableConnection implements Parcelable { destination.writeParcelable(mPhoneAccount, 0); destination.writeInt(mState); destination.writeInt(mCapabilities); - destination.writeParcelable(mHandle, 0); - destination.writeInt(mHandlePresentation); + destination.writeParcelable(mAddress, 0); + destination.writeInt(mAddressPresentation); destination.writeString(mCallerDisplayName); destination.writeInt(mCallerDisplayNamePresentation); destination.writeStrongBinder( mVideoProvider != null ? mVideoProvider.asBinder() : null); destination.writeInt(mVideoState); - destination.writeByte((byte) (mRequestingRingback ? 1 : 0)); - destination.writeByte((byte) (mAudioModeIsVoip ? 1 : 0)); + destination.writeByte((byte) (mRingbackRequested ? 1 : 0)); + destination.writeByte((byte) (mIsVoipAudioMode ? 1 : 0)); destination.writeParcelable(mStatusHints, 0); destination.writeInt(mDisconnectCause); destination.writeString(mDisconnectMessage); diff --git a/telecomm/java/android/telecomm/PhoneCapabilities.java b/telecomm/java/android/telecomm/PhoneCapabilities.java index 7a338b4..ec11376 100644 --- a/telecomm/java/android/telecomm/PhoneCapabilities.java +++ b/telecomm/java/android/telecomm/PhoneCapabilities.java @@ -78,8 +78,19 @@ public final class PhoneCapabilities { */ public static final int VoWIFI = 0x00000800; - public static final int ALL = HOLD | SUPPORT_HOLD | MERGE_CONFERENCE | SWAP_CONFERENCE | ADD_CALL - | RESPOND_VIA_TEXT | MUTE | MANAGE_CONFERENCE; + /** + * Call is able to be separated from its parent {@code Conference}, if any. + */ + public static final int SEPARATE_FROM_CONFERENCE = 0x00001000; + + /** + * Call is able to be individually disconnected when in a {@code Conference}. + */ + public static final int DISCONNECT_FROM_CONFERENCE = 0x00002000; + + public static final int ALL = HOLD | SUPPORT_HOLD | MERGE_CONFERENCE | SWAP_CONFERENCE + | ADD_CALL | RESPOND_VIA_TEXT | MUTE | MANAGE_CONFERENCE | SEPARATE_FROM_CONFERENCE + | DISCONNECT_FROM_CONFERENCE; public static String toString(int capabilities) { StringBuilder builder = new StringBuilder(); diff --git a/telecomm/java/android/telecomm/RemoteConference.java b/telecomm/java/android/telecomm/RemoteConference.java index b073827..dbff079 100644 --- a/telecomm/java/android/telecomm/RemoteConference.java +++ b/telecomm/java/android/telecomm/RemoteConference.java @@ -188,11 +188,11 @@ public final class RemoteConference { return mDisconnectMessage; } - public final void addCallback(Callback callback) { + public final void registerCallback(Callback callback) { mCallbacks.add(callback); } - public final void removeCallback(Callback callback) { + public final void unregisterCallback(Callback callback) { mCallbacks.remove(callback); } } diff --git a/telecomm/java/android/telecomm/RemoteConnection.java b/telecomm/java/android/telecomm/RemoteConnection.java index 68367f0..f3a6085 100644 --- a/telecomm/java/android/telecomm/RemoteConnection.java +++ b/telecomm/java/android/telecomm/RemoteConnection.java @@ -42,7 +42,7 @@ import java.util.concurrent.ConcurrentHashMap; */ public final class RemoteConnection { - public static abstract class Listener { + public static abstract class Callback { /** * Invoked when the state of this {@code RemoteConnection} has changed. See * {@link #getState()}. @@ -53,25 +53,6 @@ public final class RemoteConnection { public void onStateChanged(RemoteConnection connection, int state) {} /** - * Invoked when the parent of this {@code RemoteConnection} has changed. See - * {@link #getParent()}. - * - * @param connection The {@code RemoteConnection} invoking this method. - * @param parent The new parent of the {@code RemoteConnection}. - */ - public void onParentChanged(RemoteConnection connection, RemoteConnection parent) {} - - /** - * Invoked when the children of this {@code RemoteConnection} have changed. See - * {@link #getChildren()}. - * - * @param connection The {@code RemoteConnection} invoking this method. - * @param children The new children of the {@code RemoteConnection}. - */ - public void onChildrenChanged( - RemoteConnection connection, List<RemoteConnection> children) {} - - /** * Invoked when this {@code RemoteConnection} is disconnected. * * @param connection The {@code RemoteConnection} invoking this method. @@ -87,12 +68,12 @@ public final class RemoteConnection { /** * Invoked when this {@code RemoteConnection} is requesting ringback. See - * {@link #isRequestingRingback()}. + * {@link #isRingbackRequested()}. * * @param connection The {@code RemoteConnection} invoking this method. * @param ringback Whether the {@code RemoteConnection} is requesting ringback. */ - public void onRequestingRingback(RemoteConnection connection, boolean ringback) {} + public void onRingbackRequested(RemoteConnection connection, boolean ringback) {} /** * Indicates that the call capabilities of this {@code RemoteConnection} have changed. @@ -116,12 +97,12 @@ public final class RemoteConnection { /** * Indicates that the VOIP audio status of this {@code RemoteConnection} has changed. - * See {@link #getAudioModeIsVoip()}. + * See {@link #isVoipAudioMode()}. * * @param connection The {@code RemoteConnection} invoking this method. * @param isVoip Whether the new audio state of the {@code RemoteConnection} is VOIP. */ - public void onAudioModeIsVoipChanged(RemoteConnection connection, boolean isVoip) {} + public void onVoipAudioChanged(RemoteConnection connection, boolean isVoip) {} /** * Indicates that the status hints of this {@code RemoteConnection} have changed. See @@ -133,15 +114,15 @@ public final class RemoteConnection { public void onStatusHintsChanged(RemoteConnection connection, StatusHints statusHints) {} /** - * Indicates that the handle (e.g., phone number) of this {@code RemoteConnection} has - * changed. See {@link #getHandle()} and {@link #getHandlePresentation()}. + * Indicates that the address (e.g., phone number) of this {@code RemoteConnection} has + * changed. See {@link #getAddress()} and {@link #getAddressPresentation()}. * * @param connection The {@code RemoteConnection} invoking this method. - * @param handle The new handle of the {@code RemoteConnection}. - * @param presentation The presentation requirements for the handle. + * @param address The new address of the {@code RemoteConnection}. + * @param presentation The presentation requirements for the address. * See {@link TelecommManager} for valid values. */ - public void onHandleChanged(RemoteConnection connection, Uri handle, int presentation) {} + public void onAddressChanged(RemoteConnection connection, Uri address, int presentation) {} /** * Indicates that the caller display name of this {@code RemoteConnection} has changed. @@ -396,8 +377,8 @@ public final class RemoteConnection { * load factor before resizing, 1 means we only expect a single thread to * access the map so make only a single shard */ - private final Set<Listener> mListeners = Collections.newSetFromMap( - new ConcurrentHashMap<Listener, Boolean>(8, 0.9f, 1)); + private final Set<Callback> mCallbacks = Collections.newSetFromMap( + new ConcurrentHashMap<Callback, Boolean>(8, 0.9f, 1)); private final List<RemoteConnection> mConferenceableConnections = new ArrayList<>(); private final List<RemoteConnection> mUnmodifiableconferenceableConnections = Collections.unmodifiableList(mConferenceableConnections); @@ -405,15 +386,15 @@ public final class RemoteConnection { private int mState = Connection.STATE_NEW; private int mDisconnectCauseCode = DisconnectCause.NOT_VALID; private String mDisconnectCauseMessage; - private boolean mRequestingRingback; + private boolean mRingbackRequested; private boolean mConnected; private int mCallCapabilities; private int mVideoState; private VideoProvider mVideoProvider; - private boolean mAudioModeIsVoip; + private boolean mIsVoipAudioMode; private StatusHints mStatusHints; - private Uri mHandle; - private int mHandlePresentation; + private Uri mAddress; + private int mAddressPresentation; private String mCallerDisplayName; private int mCallerDisplayNamePresentation; private int mFailureCode; @@ -450,42 +431,26 @@ public final class RemoteConnection { } /** - * Adds a listener to this {@code RemoteConnection}. + * Adds a callback to this {@code RemoteConnection}. * - * @param listener A {@code Listener}. + * @param callback A {@code Callback}. */ - public void addListener(Listener listener) { - mListeners.add(listener); + public void registerCallback(Callback callback) { + mCallbacks.add(callback); } /** - * Removes a listener from this {@code RemoteConnection}. + * Removes a callback from this {@code RemoteConnection}. * - * @param listener A {@code Listener}. + * @param callback A {@code Callback}. */ - public void removeListener(Listener listener) { - if (listener != null) { - mListeners.remove(listener); + public void unregisterCallback(Callback callback) { + if (callback != null) { + mCallbacks.remove(callback); } } /** - * Obtains the parent of this {@code RemoteConnection} in a conference, if any. - * - * @return The parent {@code RemoteConnection}, or {@code null} if this {@code RemoteConnection} - * is not a child of any conference {@code RemoteConnection}s. - */ - public RemoteConnection getParent() { return null; } - - /** - * Obtains the children of this conference {@code RemoteConnection}, if any. - * - * @return The children of this {@code RemoteConnection} if this {@code RemoteConnection} is - * a conference, or an empty {@code List} otherwise. - */ - public List<RemoteConnection> getChildren() { return new ArrayList<>(); } - - /** * Obtains the state of this {@code RemoteConnection}. * * @return A state value, chosen from the {@code STATE_*} constants. @@ -522,8 +487,8 @@ public final class RemoteConnection { /** * @return {@code true} if the {@code RemoteConnection}'s current audio mode is VOIP. */ - public boolean getAudioModeIsVoip() { - return mAudioModeIsVoip; + public boolean isVoipAudioMode() { + return mIsVoipAudioMode; } /** @@ -535,25 +500,25 @@ public final class RemoteConnection { } /** - * @return The handle (e.g., phone number) to which the {@code RemoteConnection} is currently + * @return The address (e.g., phone number) to which the {@code RemoteConnection} is currently * connected. */ - public Uri getHandle() { - return mHandle; + public Uri getAddress() { + return mAddress; } /** - * @return The presentation requirements for the handle. See - * {@link TelecommManager} for valid values. + * @return The presentation requirements for the address. See {@link TelecommManager} for valid + * values. */ - public int getHandlePresentation() { - return mHandlePresentation; + public int getAddressPresentation() { + return mAddressPresentation; } /** * @return The display name for the caller. */ - public String getCallerDisplayName() { + public CharSequence getCallerDisplayName() { return mCallerDisplayName; } @@ -601,7 +566,7 @@ public final class RemoteConnection { * @return Whether the {@code RemoteConnection} is requesting that the framework play a * ringback tone on its behalf. */ - public boolean isRequestingRingback() { + public boolean isRingbackRequested() { return false; } @@ -738,8 +703,8 @@ public final class RemoteConnection { * of time. * * If the DTMF string contains a {@link TelecommManager#DTMF_CHARACTER_WAIT} symbol, this - * {@code RemoteConnection} will pause playing the tones and notify listeners via - * {@link Listener#onPostDialWait(RemoteConnection, String)}. At this point, the in-call app + * {@code RemoteConnection} will pause playing the tones and notify callbackss via + * {@link Callback#onPostDialWait(RemoteConnection, String)}. At this point, the in-call app * should display to the user an indication of this state and an affordance to continue * the postdial sequence. When the user decides to continue the postdial sequence, the in-call * app should invoke the {@link #postDialContinue(boolean)} method. @@ -806,8 +771,8 @@ public final class RemoteConnection { void setState(int state) { if (mState != state) { mState = state; - for (Listener l: mListeners) { - l.onStateChanged(this, state); + for (Callback c: mCallbacks) { + c.onStateChanged(this, state); } } } @@ -821,8 +786,8 @@ public final class RemoteConnection { mDisconnectCauseCode = cause; mDisconnectCauseMessage = message; - for (Listener l : mListeners) { - l.onDisconnected(this, cause, message); + for (Callback c : mCallbacks) { + c.onDisconnected(this, cause, message); } } } @@ -830,11 +795,11 @@ public final class RemoteConnection { /** * @hide */ - void setRequestingRingback(boolean ringback) { - if (mRequestingRingback != ringback) { - mRequestingRingback = ringback; - for (Listener l : mListeners) { - l.onRequestingRingback(this, ringback); + void setRingbackRequested(boolean ringback) { + if (mRingbackRequested != ringback) { + mRingbackRequested = ringback; + for (Callback c : mCallbacks) { + c.onRingbackRequested(this, ringback); } } } @@ -844,8 +809,8 @@ public final class RemoteConnection { */ void setCallCapabilities(int callCapabilities) { mCallCapabilities = callCapabilities; - for (Listener l : mListeners) { - l.onCallCapabilitiesChanged(this, callCapabilities); + for (Callback c : mCallbacks) { + c.onCallCapabilitiesChanged(this, callCapabilities); } } @@ -853,16 +818,16 @@ public final class RemoteConnection { * @hide */ void setDestroyed() { - if (!mListeners.isEmpty()) { - // Make sure that the listeners are notified that the call is destroyed first. + if (!mCallbacks.isEmpty()) { + // Make sure that the callbacks are notified that the call is destroyed first. if (mState != Connection.STATE_DISCONNECTED) { setDisconnected(DisconnectCause.ERROR_UNSPECIFIED, "Connection destroyed."); } - for (Listener l : mListeners) { - l.onDestroyed(this); + for (Callback c : mCallbacks) { + c.onDestroyed(this); } - mListeners.clear(); + mCallbacks.clear(); mConnected = false; } @@ -872,8 +837,8 @@ public final class RemoteConnection { * @hide */ void setPostDialWait(String remainingDigits) { - for (Listener l : mListeners) { - l.onPostDialWait(this, remainingDigits); + for (Callback c : mCallbacks) { + c.onPostDialWait(this, remainingDigits); } } @@ -882,8 +847,8 @@ public final class RemoteConnection { */ void setVideoState(int videoState) { mVideoState = videoState; - for (Listener l : mListeners) { - l.onVideoStateChanged(this, videoState); + for (Callback c : mCallbacks) { + c.onVideoStateChanged(this, videoState); } } @@ -892,33 +857,33 @@ public final class RemoteConnection { */ void setVideoProvider(VideoProvider videoProvider) { mVideoProvider = videoProvider; - for (Listener l : mListeners) { - l.onVideoProviderChanged(this, videoProvider); + for (Callback c : mCallbacks) { + c.onVideoProviderChanged(this, videoProvider); } } /** @hide */ - void setAudioModeIsVoip(boolean isVoip) { - mAudioModeIsVoip = isVoip; - for (Listener l : mListeners) { - l.onAudioModeIsVoipChanged(this, isVoip); + void setIsVoipAudioMode(boolean isVoip) { + mIsVoipAudioMode = isVoip; + for (Callback c : mCallbacks) { + c.onVoipAudioChanged(this, isVoip); } } /** @hide */ void setStatusHints(StatusHints statusHints) { mStatusHints = statusHints; - for (Listener l : mListeners) { - l.onStatusHintsChanged(this, statusHints); + for (Callback c : mCallbacks) { + c.onStatusHintsChanged(this, statusHints); } } /** @hide */ - void setHandle(Uri handle, int presentation) { - mHandle = handle; - mHandlePresentation = presentation; - for (Listener l : mListeners) { - l.onHandleChanged(this, handle, presentation); + void setAddress(Uri address, int presentation) { + mAddress = address; + mAddressPresentation = presentation; + for (Callback c : mCallbacks) { + c.onAddressChanged(this, address, presentation); } } @@ -926,8 +891,8 @@ public final class RemoteConnection { void setCallerDisplayName(String callerDisplayName, int presentation) { mCallerDisplayName = callerDisplayName; mCallerDisplayNamePresentation = presentation; - for (Listener l : mListeners) { - l.onCallerDisplayNameChanged(this, callerDisplayName, presentation); + for (Callback c : mCallbacks) { + c.onCallerDisplayNameChanged(this, callerDisplayName, presentation); } } @@ -935,8 +900,8 @@ public final class RemoteConnection { void setConferenceableConnections(List<RemoteConnection> conferenceableConnections) { mConferenceableConnections.clear(); mConferenceableConnections.addAll(conferenceableConnections); - for (Listener l : mListeners) { - l.onConferenceableConnectionsChanged(this, mUnmodifiableconferenceableConnections); + for (Callback c : mCallbacks) { + c.onConferenceableConnectionsChanged(this, mUnmodifiableconferenceableConnections); } } @@ -944,8 +909,8 @@ public final class RemoteConnection { void setConference(RemoteConference conference) { if (mConference != conference) { mConference = conference; - for (Listener l : mListeners) { - l.onConferenceChanged(this, conference); + for (Callback c : mCallbacks) { + c.onConferenceChanged(this, conference); } } } diff --git a/telecomm/java/android/telecomm/RemoteConnectionService.java b/telecomm/java/android/telecomm/RemoteConnectionService.java index 8b8e8eb..d4dd9af 100644 --- a/telecomm/java/android/telecomm/RemoteConnectionService.java +++ b/telecomm/java/android/telecomm/RemoteConnectionService.java @@ -61,7 +61,7 @@ final class RemoteConnectionService { mPendingConnections.remove(connection); // Unconditionally initialize the connection ... connection.setCallCapabilities(parcel.getCapabilities()); - connection.setHandle( + connection.setAddress( parcel.getHandle(), parcel.getHandlePresentation()); connection.setCallerDisplayName( parcel.getCallerDisplayName(), @@ -131,9 +131,9 @@ final class RemoteConnectionService { } @Override - public void setRequestingRingback(String callId, boolean ringing) { - findConnectionForAction(callId, "setRequestingRingback") - .setRequestingRingback(ringing); + public void setRingbackRequested(String callId, boolean ringing) { + findConnectionForAction(callId, "setRingbackRequested") + .setRingbackRequested(ringing); } @Override @@ -192,7 +192,7 @@ final class RemoteConnectionService { conference.setState(parcel.getState()); conference.setCallCapabilities(parcel.getCapabilities()); mConferenceById.put(callId, conference); - conference.addCallback(new RemoteConference.Callback() { + conference.registerCallback(new RemoteConference.Callback() { @Override public void onDestroyed(RemoteConference c) { mConferenceById.remove(callId); @@ -238,9 +238,9 @@ final class RemoteConnectionService { } @Override - public void setAudioModeIsVoip(String callId, boolean isVoip) { - findConnectionForAction(callId, "setAudioModeIsVoip") - .setAudioModeIsVoip(isVoip); + public void setIsVoipAudioMode(String callId, boolean isVoip) { + findConnectionForAction(callId, "setIsVoipAudioMode") + .setIsVoipAudioMode(isVoip); } @Override @@ -250,9 +250,9 @@ final class RemoteConnectionService { } @Override - public void setHandle(String callId, Uri handle, int presentation) { - findConnectionForAction(callId, "setHandle") - .setHandle(handle, presentation); + public void setAddress(String callId, Uri address, int presentation) { + findConnectionForAction(callId, "setAddress") + .setAddress(address, presentation); } @Override @@ -343,7 +343,7 @@ final class RemoteConnectionService { id, newRequest, isIncoming); - connection.addListener(new RemoteConnection.Listener() { + connection.registerCallback(new RemoteConnection.Callback() { @Override public void onDestroyed(RemoteConnection connection) { mConnectionById.remove(id); diff --git a/telecomm/java/android/telecomm/TelecommManager.java b/telecomm/java/android/telecomm/TelecommManager.java index 9b8c536..e2c98cd 100644 --- a/telecomm/java/android/telecomm/TelecommManager.java +++ b/telecomm/java/android/telecomm/TelecommManager.java @@ -70,6 +70,24 @@ public class TelecommManager { "android.telecomm.action.CHANGE_PHONE_ACCOUNTS"; /** + * The {@link android.content.Intent} action used to inform a + * {@link android.telecomm.ConnectionService} that one of its {@link PhoneAccount}s has been + * enabled. The {@link TelecommManager#EXTRA_PHONE_ACCOUNT_HANDLE} extra is used to indicate + * which {@link PhoneAccount} has been enabled. + */ + public static final String ACTION_PHONE_ACCOUNT_ENABLED = + "android.telecom.action.PHONE_ACCOUNT_ENABLED"; + + /** + * The {@link android.content.Intent} action used to inform a + * {@link android.telecomm.ConnectionService} that one of its {@link PhoneAccount}s has been + * disabled. The {@link TelecommManager#EXTRA_PHONE_ACCOUNT_HANDLE} extra is used to indicate + * which {@link PhoneAccount} has been disabled. + */ + public static final String ACTION_PHONE_ACCOUNT_DISABLED = + "android.telecom.action.PHONE_ACCOUNT_DISABLED"; + + /** * Optional extra for {@link android.content.Intent#ACTION_CALL} containing a boolean that * determines whether the speakerphone should be automatically turned on for an outgoing call. */ @@ -142,6 +160,30 @@ public class TelecommManager { "android.telecomm.extra.CONNECTION_SERVICE"; /** + * An optional {@link android.content.Intent#ACTION_CALL} intent extra denoting the + * package name of the app specifying an alternative gateway for the call. + * The value is a string. + * + * (The following comment corresponds to the all GATEWAY_* extras) + * An app which sends the {@link android.content.Intent#ACTION_CALL} intent can specify an + * alternative address to dial which is different from the one specified and displayed to + * the user. This alternative address is referred to as the gateway address. + */ + public static final String GATEWAY_PROVIDER_PACKAGE = + "android.telecomm.extra.GATEWAY_PROVIDER_PACKAGE"; + + /** + * An optional {@link android.content.Intent#ACTION_CALL} intent extra corresponding to the + * original address to dial for the call. This is used when an alternative gateway address is + * provided to recall the original address. + * The value is a {@link android.net.Uri}. + * + * (See {@link #GATEWAY_PROVIDER_PACKAGE} for details) + */ + public static final String GATEWAY_ORIGINAL_ADDRESS = + "android.telecomm.extra.GATEWAY_ORIGINAL_ADDRESS"; + + /** * The number which the party on the other side of the line will see (and use to return the * call). * <p> @@ -288,7 +330,7 @@ public class TelecommManager { * <p> * Apps must be prepared for this method to return {@code null}, indicating that there currently * exists no user-chosen default {@code PhoneAccount}. In this case, apps wishing to initiate a - * phone call must either create their {@link android.content .Intent#ACTION_CALL} or + * phone call must either create their {@link android.content.Intent#ACTION_CALL} or * {@link android.content.Intent#ACTION_DIAL} {@code Intent} with no * {@link TelecommManager#EXTRA_PHONE_ACCOUNT_HANDLE}, or present the user with an affordance to * select one of the elements of {@link #getEnabledPhoneAccounts()}. @@ -579,15 +621,13 @@ public class TelecommManager { } /** - * Remove all Accounts for a given package from the system. - * - * @param packageName A package name that may have registered Accounts. + * Remove all Accounts that belong to the calling package from the system. */ @SystemApi - public void clearAccounts(String packageName) { + public void clearAccounts() { try { if (isServiceConnected()) { - getTelecommService().clearAccounts(packageName); + getTelecommService().clearAccounts(mContext.getPackageName()); } } catch (RemoteException e) { Log.e(TAG, "Error calling ITelecommService#clearAccounts", e); diff --git a/telecomm/java/com/android/internal/telecomm/IConnectionServiceAdapter.aidl b/telecomm/java/com/android/internal/telecomm/IConnectionServiceAdapter.aidl index 610178e..4b636d1 100644 --- a/telecomm/java/com/android/internal/telecomm/IConnectionServiceAdapter.aidl +++ b/telecomm/java/com/android/internal/telecomm/IConnectionServiceAdapter.aidl @@ -49,7 +49,7 @@ oneway interface IConnectionServiceAdapter { void setOnHold(String callId); - void setRequestingRingback(String callId, boolean ringing); + void setRingbackRequested(String callId, boolean ringing); void setCallCapabilities(String callId, int callCapabilities); @@ -67,11 +67,11 @@ oneway interface IConnectionServiceAdapter { void setVideoState(String callId, int videoState); - void setAudioModeIsVoip(String callId, boolean isVoip); + void setIsVoipAudioMode(String callId, boolean isVoip); void setStatusHints(String callId, in StatusHints statusHints); - void setHandle(String callId, in Uri handle, int presentation); + void setAddress(String callId, in Uri address, int presentation); void setCallerDisplayName(String callId, String callerDisplayName, int presentation); diff --git a/telephony/java/android/telephony/SubscriptionManager.java b/telephony/java/android/telephony/SubscriptionManager.java index d0f355e..fe68263 100644 --- a/telephony/java/android/telephony/SubscriptionManager.java +++ b/telephony/java/android/telephony/SubscriptionManager.java @@ -930,13 +930,20 @@ public class SubscriptionManager implements BaseColumns { /** @hide */ public static boolean isValidSlotId(int slotId) { - return slotId > INVALID_SLOT_ID && slotId < TelephonyManager.getDefault().getSimCount(); + // We are testing INVALID_SLOT_ID and slotId >= 0 independently because we should + // not assume that INVALID_SLOT_ID will always be a negative value. Any negative + // value is invalid. + return slotId != INVALID_SLOT_ID && slotId >= 0 && + slotId < TelephonyManager.getDefault().getSimCount(); } /** @hide */ public static boolean isValidPhoneId(int phoneId) { - return phoneId > INVALID_PHONE_ID - && phoneId < TelephonyManager.getDefault().getPhoneCount(); + // We are testing INVALID_PHONE_ID and phoneId >= 0 independently because we should + // not assume that INVALID_PHONE_ID will always be a negative value. Any negative + // value is invalid. + return phoneId != INVALID_PHONE_ID && phoneId >= 0 && + phoneId < TelephonyManager.getDefault().getPhoneCount(); } /** @hide */ diff --git a/tests/StatusBar/src/com/android/statusbartest/PowerTest.java b/tests/StatusBar/src/com/android/statusbartest/PowerTest.java index 2ec620b..52527d9 100644 --- a/tests/StatusBar/src/com/android/statusbartest/PowerTest.java +++ b/tests/StatusBar/src/com/android/statusbartest/PowerTest.java @@ -77,9 +77,9 @@ public class PowerTest extends TestActivity mProx.release(); } }, - new Test("Disable proximity (WAIT_FOR_DISTANT_PROXIMITY") { + new Test("Disable proximity (RELEASE_FLAG_WAIT_FOR_NO_PROXIMITY") { public void run() { - mProx.release(PowerManager.WAIT_FOR_DISTANT_PROXIMITY); + mProx.release(PowerManager.RELEASE_FLAG_WAIT_FOR_NO_PROXIMITY); } }, new Test("Enable proximity, wait 5 seconds then disable") { @@ -93,13 +93,14 @@ public class PowerTest extends TestActivity }, 5000); } }, - new Test("Enable proximity, wait 5 seconds then disable (WAIT_FOR_DISTANT_PROXIMITY)") { + new Test("Enable proximity, wait 5 seconds then disable " + + "(RELEASE_FLAG_WAIT_FOR_NO_PROXIMITY)") { public void run() { mProx.acquire(); mHandler.postDelayed(new Runnable() { @Override public void run() { - mProx.release(PowerManager.WAIT_FOR_DISTANT_PROXIMITY); + mProx.release(PowerManager.RELEASE_FLAG_WAIT_FOR_NO_PROXIMITY); } }, 5000); } diff --git a/tests/UsageStatsTest/src/com/android/tests/usagestats/UsageLogActivity.java b/tests/UsageStatsTest/src/com/android/tests/usagestats/UsageLogActivity.java index 31e7c38..d9a3b61 100644 --- a/tests/UsageStatsTest/src/com/android/tests/usagestats/UsageLogActivity.java +++ b/tests/UsageStatsTest/src/com/android/tests/usagestats/UsageLogActivity.java @@ -86,7 +86,10 @@ public class UsageLogActivity extends ListActivity implements Runnable { } mEvents.addFirst(event); } - notifyDataSetChanged(); + + if (lastTimeStamp != 0) { + notifyDataSetChanged(); + } return lastTimeStamp; } |
