summaryrefslogtreecommitdiffstats
path: root/core/java
diff options
context:
space:
mode:
Diffstat (limited to 'core/java')
-rw-r--r--core/java/android/app/Activity.java7
-rw-r--r--core/java/android/app/ActivityManager.java22
-rw-r--r--core/java/android/app/AppOpsManager.java3
-rw-r--r--core/java/android/app/ExitTransitionCoordinator.java2
-rw-r--r--core/java/android/app/Fragment.java6
-rw-r--r--core/java/android/app/FragmentHostCallback.java17
-rw-r--r--core/java/android/app/FragmentManager.java8
-rw-r--r--core/java/android/app/IntentService.java2
-rw-r--r--core/java/android/app/Notification.java1
-rw-r--r--core/java/android/app/SearchDialog.java16
-rw-r--r--core/java/android/app/admin/DeviceAdminReceiver.java8
-rw-r--r--core/java/android/app/admin/DevicePolicyManager.java24
-rw-r--r--core/java/android/app/admin/IDevicePolicyManager.aidl4
-rw-r--r--core/java/android/app/trust/ITrustManager.aidl1
-rw-r--r--core/java/android/app/trust/TrustManager.java17
-rw-r--r--core/java/android/bluetooth/BluetoothAdapter.java3
-rw-r--r--core/java/android/bluetooth/BluetoothHealthCallback.java3
-rw-r--r--core/java/android/bluetooth/BluetoothSap.java59
-rw-r--r--core/java/android/bluetooth/BluetoothSocket.java10
-rw-r--r--core/java/android/bluetooth/le/ScanCallback.java6
-rw-r--r--core/java/android/bluetooth/le/ScanSettings.java11
-rw-r--r--core/java/android/content/pm/ActivityInfo.java24
-rw-r--r--core/java/android/content/pm/IPackageManager.aidl4
-rw-r--r--core/java/android/content/res/AssetManager.java1
-rw-r--r--core/java/android/content/res/Resources.java13
-rw-r--r--core/java/android/net/ConnectivityManager.java4
-rw-r--r--core/java/android/os/AsyncTask.java13
-rw-r--r--core/java/android/os/Bundle.java8
-rw-r--r--core/java/android/os/storage/StorageManager.java2
-rw-r--r--core/java/android/preference/GenericInflater.java1
-rw-r--r--core/java/android/provider/ContactsContract.java10
-rw-r--r--core/java/android/service/carrier/CarrierMessagingService.java77
-rw-r--r--core/java/android/service/carrier/ICarrierMessagingService.aidl9
-rw-r--r--core/java/android/service/notification/ZenModeConfig.java110
-rw-r--r--core/java/android/service/voice/IVoiceInteractionService.aidl1
-rw-r--r--core/java/android/service/voice/VoiceInteractionService.java21
-rw-r--r--core/java/android/service/voice/VoiceInteractionServiceInfo.java8
-rw-r--r--core/java/android/text/Html.java2
-rw-r--r--core/java/android/transition/Transition.java3
-rw-r--r--core/java/android/transition/TransitionInflater.java2
-rw-r--r--core/java/android/transition/Visibility.java117
-rw-r--r--core/java/android/view/DisplayListCanvas.java6
-rw-r--r--core/java/android/view/LayoutInflater.java2
-rw-r--r--core/java/android/view/MenuInflater.java1
-rw-r--r--core/java/android/view/ThreadedRenderer.java9
-rw-r--r--core/java/android/view/View.java347
-rw-r--r--core/java/android/view/ViewGroup.java18
-rw-r--r--core/java/android/view/accessibility/AccessibilityNodeInfo.java28
-rw-r--r--core/java/android/widget/AbsListView.java8
-rw-r--r--core/java/android/widget/CursorAdapter.java2
-rw-r--r--core/java/android/widget/Editor.java8
-rw-r--r--core/java/android/widget/HorizontalScrollView.java14
-rw-r--r--core/java/android/widget/ListPopupWindow.java18
-rw-r--r--core/java/android/widget/PopupWindow.java6
-rw-r--r--core/java/android/widget/RemoteViewsAdapter.java10
-rw-r--r--core/java/android/widget/ScrollView.java13
-rw-r--r--core/java/com/android/internal/app/AlertController.java74
-rw-r--r--core/java/com/android/internal/app/IVoiceInteractionManagerService.aidl12
-rw-r--r--core/java/com/android/internal/os/BinderInternal.java4
-rw-r--r--core/java/com/android/internal/os/MobileRadioPowerCalculator.java6
-rw-r--r--core/java/com/android/internal/widget/ButtonBarLayout.java38
-rw-r--r--core/java/com/android/internal/widget/ViewPager.java6
62 files changed, 1011 insertions, 279 deletions
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index e79e20c..7260d10 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -21,6 +21,7 @@ import android.annotation.DrawableRes;
import android.annotation.IdRes;
import android.annotation.IntDef;
import android.annotation.LayoutRes;
+import android.annotation.MainThread;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.StyleRes;
@@ -891,6 +892,7 @@ public class Activity extends ContextThemeWrapper
* @see #onRestoreInstanceState
* @see #onPostCreate
*/
+ @MainThread
@CallSuper
protected void onCreate(@Nullable Bundle savedInstanceState) {
if (DEBUG_LIFECYCLE) Slog.v(TAG, "onCreate " + this + ": " + savedInstanceState);
@@ -6496,6 +6498,11 @@ public class Activity extends ContextThemeWrapper
return (w == null) ? 0 : w.getAttributes().windowAnimations;
}
+ @Override
+ public void onAttachFragment(Fragment fragment) {
+ Activity.this.onAttachFragment(fragment);
+ }
+
@Nullable
@Override
public View onFindViewById(int id) {
diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java
index 576a046..9bbb4be 100644
--- a/core/java/android/app/ActivityManager.java
+++ b/core/java/android/app/ActivityManager.java
@@ -16,8 +16,10 @@
package android.app;
+import android.Manifest;
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.annotation.RequiresPermission;
import android.annotation.SystemApi;
import android.graphics.Canvas;
import android.graphics.Matrix;
@@ -26,6 +28,7 @@ import android.os.BatteryStats;
import android.os.IBinder;
import android.os.ParcelFileDescriptor;
+import android.util.Log;
import com.android.internal.app.ProcessStats;
import com.android.internal.os.TransferPipe;
import com.android.internal.util.FastPrintWriter;
@@ -2396,7 +2399,24 @@ public class ActivityManager {
} catch (RemoteException e) {
}
}
-
+
+ /**
+ * Kills the specified UID.
+ * @param uid The UID to kill.
+ * @param reason The reason for the kill.
+ *
+ * @hide
+ */
+ @SystemApi
+ @RequiresPermission(Manifest.permission.KILL_UID)
+ public void killUid(int uid, String reason) {
+ try {
+ ActivityManagerNative.getDefault().killUid(uid, reason);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Couldn't kill uid:" + uid, e);
+ }
+ }
+
/**
* Have the system perform a force stop of everything associated with
* the given application package. All processes that share its uid
diff --git a/core/java/android/app/AppOpsManager.java b/core/java/android/app/AppOpsManager.java
index 6bbbf9e..5aa399b 100644
--- a/core/java/android/app/AppOpsManager.java
+++ b/core/java/android/app/AppOpsManager.java
@@ -941,7 +941,8 @@ public class AppOpsManager {
* @hide
*/
public static int permissionToOpCode(String permission) {
- return sPermToOp.get(permission);
+ Integer boxedOpCode = sPermToOp.get(permission);
+ return boxedOpCode != null ? boxedOpCode : OP_NONE;
}
/**
diff --git a/core/java/android/app/ExitTransitionCoordinator.java b/core/java/android/app/ExitTransitionCoordinator.java
index 169952a..0f286fb 100644
--- a/core/java/android/app/ExitTransitionCoordinator.java
+++ b/core/java/android/app/ExitTransitionCoordinator.java
@@ -239,7 +239,7 @@ class ExitTransitionCoordinator extends ActivityTransitionCoordinator {
getWindow().setBackgroundDrawable(new ColorDrawable(Color.BLACK));
}
ActivityOptions options = ActivityOptions.makeSceneTransitionAnimation(mActivity, this,
- mAllSharedElementNames, resultCode, data);
+ mSharedElementNames, resultCode, data);
mActivity.convertToTranslucent(new Activity.TranslucentConversionListener() {
@Override
public void onTranslucentConversionComplete(boolean drawComplete) {
diff --git a/core/java/android/app/Fragment.java b/core/java/android/app/Fragment.java
index 91d810e..40c5c64 100644
--- a/core/java/android/app/Fragment.java
+++ b/core/java/android/app/Fragment.java
@@ -1314,6 +1314,12 @@ public class Fragment implements ComponentCallbacks2, OnCreateContextMenuListene
com.android.internal.R.styleable.Fragment_fragmentAllowReturnTransitionOverlap, true);
}
a.recycle();
+
+ final Activity hostActivity = mHost == null ? null : mHost.getActivity();
+ if (hostActivity != null) {
+ mCalled = false;
+ onInflate(hostActivity, attrs, savedInstanceState);
+ }
}
/**
diff --git a/core/java/android/app/FragmentHostCallback.java b/core/java/android/app/FragmentHostCallback.java
index dad2c79..3e753f0 100644
--- a/core/java/android/app/FragmentHostCallback.java
+++ b/core/java/android/app/FragmentHostCallback.java
@@ -23,7 +23,6 @@ import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.util.ArrayMap;
-import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
@@ -140,6 +139,14 @@ public abstract class FragmentHostCallback<E> extends FragmentContainer {
return mWindowAnimations;
}
+ /**
+ * Called when a {@link Fragment} is being attached to this host, immediately
+ * after the call to its {@link Fragment#onAttach(Context)} method and before
+ * {@link Fragment#onCreate(Bundle)}.
+ */
+ public void onAttachFragment(Fragment fragment) {
+ }
+
@Nullable
@Override
public View onFindViewById(int id) {
@@ -187,14 +194,6 @@ public abstract class FragmentHostCallback<E> extends FragmentContainer {
}
}
- void onFragmentInflate(Fragment fragment, AttributeSet attrs, Bundle savedInstanceState) {
- fragment.onInflate(mContext, attrs, savedInstanceState);
- }
-
- void onFragmentAttach(Fragment fragment) {
- fragment.onAttach(mContext);
- }
-
void doLoaderStart() {
if (mLoadersStarted) {
return;
diff --git a/core/java/android/app/FragmentManager.java b/core/java/android/app/FragmentManager.java
index 62436e9..6b5239d 100644
--- a/core/java/android/app/FragmentManager.java
+++ b/core/java/android/app/FragmentManager.java
@@ -844,13 +844,13 @@ final class FragmentManagerImpl extends FragmentManager implements LayoutInflate
f.mFragmentManager = mParent != null
? mParent.mChildFragmentManager : mHost.getFragmentManagerImpl();
f.mCalled = false;
- mHost.onFragmentAttach(f);
+ f.onAttach(mHost.getContext());
if (!f.mCalled) {
throw new SuperNotCalledException("Fragment " + f
+ " did not call through to super.onAttach()");
}
if (f.mParentFragment == null) {
- mHost.onFragmentAttach(f);
+ mHost.onAttachFragment(f);
}
if (!f.mRetaining) {
@@ -2107,7 +2107,7 @@ final class FragmentManagerImpl extends FragmentManager implements LayoutInflate
fragment.mTag = tag;
fragment.mInLayout = true;
fragment.mFragmentManager = this;
- mHost.onFragmentInflate(fragment, attrs, fragment.mSavedFragmentState);
+ fragment.onInflate(mHost.getContext(), attrs, fragment.mSavedFragmentState);
addFragment(fragment, true);
} else if (fragment.mInLayout) {
// A fragment already exists and it is not one we restored from
@@ -2124,7 +2124,7 @@ final class FragmentManagerImpl extends FragmentManager implements LayoutInflate
// from last saved state), then give it the attributes to
// initialize itself.
if (!fragment.mRetaining) {
- mHost.onFragmentInflate(fragment, attrs, fragment.mSavedFragmentState);
+ fragment.onInflate(mHost.getContext(), attrs, fragment.mSavedFragmentState);
}
}
diff --git a/core/java/android/app/IntentService.java b/core/java/android/app/IntentService.java
index 96767ae..3cda973 100644
--- a/core/java/android/app/IntentService.java
+++ b/core/java/android/app/IntentService.java
@@ -16,6 +16,7 @@
package android.app;
+import android.annotation.WorkerThread;
import android.content.Intent;
import android.os.Handler;
import android.os.HandlerThread;
@@ -158,5 +159,6 @@ public abstract class IntentService extends Service {
* @param intent The value passed to {@link
* android.content.Context#startService(Intent)}.
*/
+ @WorkerThread
protected abstract void onHandleIntent(Intent intent);
}
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index ff589f9..49b2549 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -2095,6 +2095,7 @@ public class Notification implements Parcelable
try {
Constructor<? extends Style> constructor = styleClass.getConstructor();
+ constructor.setAccessible(true);
style = constructor.newInstance();
style.restoreFromExtras(extras);
} catch (Throwable t) {
diff --git a/core/java/android/app/SearchDialog.java b/core/java/android/app/SearchDialog.java
index b1a5d21..fa11221 100644
--- a/core/java/android/app/SearchDialog.java
+++ b/core/java/android/app/SearchDialog.java
@@ -165,8 +165,6 @@ public class SearchDialog extends Dialog {
setContentView(com.android.internal.R.layout.search_bar);
// get the view elements for local access
- SearchBar searchBar = (SearchBar) findViewById(com.android.internal.R.id.search_bar);
- searchBar.setSearchDialog(this);
mSearchView = (SearchView) findViewById(com.android.internal.R.id.search_view);
mSearchView.setIconified(false);
mSearchView.setOnCloseListener(mOnCloseListener);
@@ -618,8 +616,6 @@ public class SearchDialog extends Dialog {
*/
public static class SearchBar extends LinearLayout {
- private SearchDialog mSearchDialog;
-
public SearchBar(Context context, AttributeSet attrs) {
super(context, attrs);
}
@@ -628,18 +624,6 @@ public class SearchDialog extends Dialog {
super(context);
}
- public void setSearchDialog(SearchDialog searchDialog) {
- mSearchDialog = searchDialog;
- }
-
- /**
- * Don't allow action modes in a SearchBar, it looks silly.
- */
- @Override
- public ActionMode startActionModeForChild(View child, ActionMode.Callback callback) {
- return null;
- }
-
@Override
public ActionMode startActionModeForChild(
View child, ActionMode.Callback callback, int type) {
diff --git a/core/java/android/app/admin/DeviceAdminReceiver.java b/core/java/android/app/admin/DeviceAdminReceiver.java
index aea413d..470804d 100644
--- a/core/java/android/app/admin/DeviceAdminReceiver.java
+++ b/core/java/android/app/admin/DeviceAdminReceiver.java
@@ -231,7 +231,7 @@ public class DeviceAdminReceiver extends BroadcastReceiver {
* device owner app.
*
* <p>The broadcast will be limited to the {@link DeviceAdminReceiver} component specified in
- * the (@link DevicePolicyManager#EXTRA_PROVISIONING_DEVICE_INITIALIZER_COMPONENT_NAME) field
+ * the {@link DevicePolicyManager#EXTRA_PROVISIONING_DEVICE_INITIALIZER_COMPONENT_NAME} field
* of the original intent or NFC bump that started the provisioning process. You will generally
* handle this in {@link DeviceAdminReceiver#onReadyForUserInitialization}.
*
@@ -450,9 +450,9 @@ public class DeviceAdminReceiver extends BroadcastReceiver {
*
* <p>It is not assumed that the device initializer is finished when it returns from
* this call, as it may do additional setup asynchronously. The device initializer must call
- * {DevicePolicyManager#setUserEnabled(ComponentName admin)} when it has finished any additional
- * setup (such as adding an account by using the {@link AccountManager}) in order for the user
- * to be functional.
+ * {@link DevicePolicyManager#setUserEnabled(ComponentName admin)} when it has finished any
+ * additional setup (such as adding an account by using the {@link AccountManager}) in order for
+ * the user to be functional.
*
* @param context The running context as per {@link #onReceive}.
* @param intent The received intent as per {@link #onReceive}.
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index 9f71ea5..8009b6c 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -412,7 +412,7 @@ public class DevicePolicyManager {
= "android.app.action.MANAGED_PROFILE_PROVISIONED";
/**
- * A boolean extra indicating whether device encryption is required as part of Device Owner
+ * A boolean extra indicating whether device encryption can be skipped as part of Device Owner
* provisioning.
*
* <p>Use in an NFC record with {@link #MIME_TYPE_PROVISIONING_NFC_V2} that starts device owner
@@ -4294,14 +4294,14 @@ public class DevicePolicyManager {
* being disabled.
*
* @param admin Which {@link DeviceAdminReceiver} this request is associated with.
- * @param enabled New state of the keyguard.
+ * @param disabled {@code true} disables the keyguard, {@code false} reenables it.
*
* @return {@code false} if attempting to disable the keyguard while a lock password was in
- * place. {@code true} otherwise."
+ * place. {@code true} otherwise.
*/
- public boolean setKeyguardEnabledState(ComponentName admin, boolean enabled) {
+ public boolean setKeyguardDisabled(ComponentName admin, boolean disabled) {
try {
- return mService.setKeyguardEnabledState(admin, enabled);
+ return mService.setKeyguardDisabled(admin, disabled);
} catch (RemoteException re) {
Log.w(TAG, "Failed talking with device policy service", re);
return false;
@@ -4309,18 +4309,22 @@ public class DevicePolicyManager {
}
/**
- * Called by device owner to set the enabled state of the status bar. Disabling the status
- * bar blocks notifications, quick settings and other screen overlays that allow escaping from
+ * Called by device owner to disable the status bar. Disabling the status bar blocks
+ * notifications, quick settings and other screen overlays that allow escaping from
* a single use device.
*
* @param admin Which {@link DeviceAdminReceiver} this request is associated with.
- * @param enabled New state of the status bar.
+ * @param disabled {@code true} disables the status bar, {@code false} reenables it.
+ *
+ * @return {@code false} if attempting to disable the status bar failed.
+ * {@code true} otherwise.
*/
- public void setStatusBarEnabledState(ComponentName admin, boolean enabled) {
+ public boolean setStatusBarDisabled(ComponentName admin, boolean disabled) {
try {
- mService.setStatusBarEnabledState(admin, enabled);
+ return mService.setStatusBarDisabled(admin, disabled);
} catch (RemoteException re) {
Log.w(TAG, "Failed talking with device policy service", re);
+ return false;
}
}
diff --git a/core/java/android/app/admin/IDevicePolicyManager.aidl b/core/java/android/app/admin/IDevicePolicyManager.aidl
index 833bc00..e81e7c1 100644
--- a/core/java/android/app/admin/IDevicePolicyManager.aidl
+++ b/core/java/android/app/admin/IDevicePolicyManager.aidl
@@ -224,8 +224,8 @@ interface IDevicePolicyManager {
void setSystemUpdatePolicy(in ComponentName who, in PersistableBundle policy);
PersistableBundle getSystemUpdatePolicy();
- boolean setKeyguardEnabledState(in ComponentName admin, boolean enabled);
- void setStatusBarEnabledState(in ComponentName who, boolean enabled);
+ boolean setKeyguardDisabled(in ComponentName admin, boolean disabled);
+ boolean setStatusBarDisabled(in ComponentName who, boolean disabled);
boolean getDoNotAskCredentialsOnBoot();
void notifyPendingSystemUpdate(in long updateReceivedTime);
diff --git a/core/java/android/app/trust/ITrustManager.aidl b/core/java/android/app/trust/ITrustManager.aidl
index 17cff5c..32951d9 100644
--- a/core/java/android/app/trust/ITrustManager.aidl
+++ b/core/java/android/app/trust/ITrustManager.aidl
@@ -32,4 +32,5 @@ interface ITrustManager {
void reportKeyguardShowingChanged();
boolean isDeviceLocked(int userId);
boolean isDeviceSecure(int userId);
+ boolean hasUserAuthenticatedSinceBoot(int userId);
}
diff --git a/core/java/android/app/trust/TrustManager.java b/core/java/android/app/trust/TrustManager.java
index b5c5317..8cab565 100644
--- a/core/java/android/app/trust/TrustManager.java
+++ b/core/java/android/app/trust/TrustManager.java
@@ -147,6 +147,23 @@ public class TrustManager {
}
}
+ /**
+ * Checks whether the specified user has been authenticated since the last boot.
+ *
+ * @param userId the user id of the user to check for
+ * @return true if the user has authenticated since boot, false otherwise
+ *
+ * Requires the {@link android.Manifest.permission#ACCESS_KEYGUARD_SECURE_STORAGE} permission.
+ */
+ public boolean hasUserAuthenticatedSinceBoot(int userId) {
+ try {
+ return mService.hasUserAuthenticatedSinceBoot(userId);
+ } catch (RemoteException e) {
+ onError(e);
+ return false;
+ }
+ }
+
private void onError(Exception e) {
Log.e(TAG, "Error while calling TrustManagerService", e);
}
diff --git a/core/java/android/bluetooth/BluetoothAdapter.java b/core/java/android/bluetooth/BluetoothAdapter.java
index 9b4dcc6..0a77868 100644
--- a/core/java/android/bluetooth/BluetoothAdapter.java
+++ b/core/java/android/bluetooth/BluetoothAdapter.java
@@ -1692,7 +1692,8 @@ public final class BluetoothAdapter {
* @param context Context of the application
* @param listener The service Listener for connection callbacks.
* @param profile The Bluetooth profile; either {@link BluetoothProfile#HEALTH},
- * {@link BluetoothProfile#HEADSET} or {@link BluetoothProfile#A2DP}.
+ * {@link BluetoothProfile#HEADSET}, {@link BluetoothProfile#A2DP}.
+ * {@link BluetoothProfile#GATT} or {@link BluetoothProfile#GATT_SERVER}.
* @return true on success, false on error
*/
public boolean getProfileProxy(Context context, BluetoothProfile.ServiceListener listener,
diff --git a/core/java/android/bluetooth/BluetoothHealthCallback.java b/core/java/android/bluetooth/BluetoothHealthCallback.java
index baf2ade..128376f 100644
--- a/core/java/android/bluetooth/BluetoothHealthCallback.java
+++ b/core/java/android/bluetooth/BluetoothHealthCallback.java
@@ -17,6 +17,7 @@
package android.bluetooth;
+import android.annotation.BinderThread;
import android.os.ParcelFileDescriptor;
import android.util.Log;
@@ -39,6 +40,7 @@ public abstract class BluetoothHealthCallback {
* {@link BluetoothHealth#APP_CONFIG_UNREGISTRATION_SUCCESS} or
* {@link BluetoothHealth#APP_CONFIG_UNREGISTRATION_FAILURE}
*/
+ @BinderThread
public void onHealthAppConfigurationStatusChange(BluetoothHealthAppConfiguration config,
int status) {
Log.d(TAG, "onHealthAppConfigurationStatusChange: " + config + "Status: " + status);
@@ -58,6 +60,7 @@ public abstract class BluetoothHealthCallback {
* @param channelId The id associated with the channel. This id will be used
* in future calls like when disconnecting the channel.
*/
+ @BinderThread
public void onHealthChannelStateChange(BluetoothHealthAppConfiguration config,
BluetoothDevice device, int prevState, int newState, ParcelFileDescriptor fd,
int channelId) {
diff --git a/core/java/android/bluetooth/BluetoothSap.java b/core/java/android/bluetooth/BluetoothSap.java
index 7b4c6f9..014cb22 100644
--- a/core/java/android/bluetooth/BluetoothSap.java
+++ b/core/java/android/bluetooth/BluetoothSap.java
@@ -28,13 +28,41 @@ import android.os.IBinder;
import android.os.ServiceManager;
import android.util.Log;
-
+/**
+ * This class provides the APIs to control the Bluetooth SIM
+ * Access Profile (SAP).
+ *
+ * <p>BluetoothSap is a proxy object for controlling the Bluetooth
+ * Service via IPC. Use {@link BluetoothAdapter#getProfileProxy} to get
+ * the BluetoothSap proxy object.
+ *
+ * <p>Each method is protected with its appropriate permission.
+ * @hide
+ */
public final class BluetoothSap implements BluetoothProfile {
private static final String TAG = "BluetoothSap";
private static final boolean DBG = true;
private static final boolean VDBG = false;
+ /**
+ * Intent used to broadcast the change in connection state of the profile.
+ *
+ * <p>This intent will have 4 extras:
+ * <ul>
+ * <li> {@link #EXTRA_STATE} - The current state of the profile. </li>
+ * <li> {@link #EXTRA_PREVIOUS_STATE}- The previous state of the profile.</li>
+ * <li> {@link BluetoothDevice#EXTRA_DEVICE} - The remote device. </li>
+ * </ul>
+ *
+ * <p>{@link #EXTRA_STATE} or {@link #EXTRA_PREVIOUS_STATE} can be any of
+ * {@link #STATE_DISCONNECTED}, {@link #STATE_CONNECTING},
+ * {@link #STATE_CONNECTED}, {@link #STATE_DISCONNECTING}.
+ *
+ * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission to
+ * receive.
+ * @hide
+ */
public static final String ACTION_CONNECTION_STATE_CHANGED =
"android.bluetooth.sap.profile.action.CONNECTION_STATE_CHANGED";
@@ -43,12 +71,22 @@ public final class BluetoothSap implements BluetoothProfile {
private ServiceListener mServiceListener;
private BluetoothAdapter mAdapter;
- /** There was an error trying to obtain the state */
- public static final int STATE_ERROR = -1;
+ /**
+ * There was an error trying to obtain the state.
+ * @hide
+ */
+ public static final int STATE_ERROR = -1;
- public static final int RESULT_FAILURE = 0;
+ /**
+ * Connection state change succceeded.
+ * @hide
+ */
public static final int RESULT_SUCCESS = 1;
- /** Connection canceled before completion. */
+
+ /**
+ * Connection canceled before completion.
+ * @hide
+ */
public static final int RESULT_CANCELED = 2;
final private IBluetoothStateChangeCallback mBluetoothStateChangeCallback =
@@ -124,6 +162,7 @@ public final class BluetoothSap implements BluetoothProfile {
* Other public functions of BluetoothSap will return default error
* results once close() has been called. Multiple invocations of close()
* are ok.
+ * @hide
*/
public synchronized void close() {
IBluetoothManager mgr = mAdapter.getBluetoothManager();
@@ -152,6 +191,7 @@ public final class BluetoothSap implements BluetoothProfile {
* Get the current state of the BluetoothSap service.
* @return One of the STATE_ return codes, or STATE_ERROR if this proxy
* object is currently not connected to the Sap service.
+ * @hide
*/
public int getState() {
if (VDBG) log("getState()");
@@ -171,6 +211,7 @@ public final class BluetoothSap implements BluetoothProfile {
* @return The remote Bluetooth device, or null if not in connected or
* connecting state, or if this proxy object is not connected to
* the Sap service.
+ * @hide
*/
public BluetoothDevice getClient() {
if (VDBG) log("getClient()");
@@ -189,6 +230,7 @@ public final class BluetoothSap implements BluetoothProfile {
* Returns true if the specified Bluetooth device is connected.
* Returns false if not connected, or if this proxy object is not
* currently connected to the Sap service.
+ * @hide
*/
public boolean isConnected(BluetoothDevice device) {
if (VDBG) log("isConnected(" + device + ")");
@@ -206,6 +248,7 @@ public final class BluetoothSap implements BluetoothProfile {
/**
* Initiate connection. Initiation of outgoing connections is not
* supported for SAP server.
+ * @hide
*/
public boolean connect(BluetoothDevice device) {
if (DBG) log("connect(" + device + ")" + "not supported for SAPS");
@@ -218,6 +261,7 @@ public final class BluetoothSap implements BluetoothProfile {
* @param device Remote Bluetooth Device
* @return false on error,
* true otherwise
+ * @hide
*/
public boolean disconnect(BluetoothDevice device) {
if (DBG) log("disconnect(" + device + ")");
@@ -238,6 +282,7 @@ public final class BluetoothSap implements BluetoothProfile {
* Get the list of connected devices. Currently at most one.
*
* @return list of connected devices
+ * @hide
*/
public List<BluetoothDevice> getConnectedDevices() {
if (DBG) log("getConnectedDevices()");
@@ -257,6 +302,7 @@ public final class BluetoothSap implements BluetoothProfile {
* Get the list of devices matching specified states. Currently at most one.
*
* @return list of matching devices
+ * @hide
*/
public List<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states) {
if (DBG) log("getDevicesMatchingStates()");
@@ -276,6 +322,7 @@ public final class BluetoothSap implements BluetoothProfile {
* Get connection state of device
*
* @return device connection state
+ * @hide
*/
public int getConnectionState(BluetoothDevice device) {
if (DBG) log("getConnectionState(" + device + ")");
@@ -300,6 +347,7 @@ public final class BluetoothSap implements BluetoothProfile {
* @param device Paired bluetooth device
* @param priority
* @return true if priority is set, false on error
+ * @hide
*/
public boolean setPriority(BluetoothDevice device, int priority) {
if (DBG) log("setPriority(" + device + ", " + priority + ")");
@@ -325,6 +373,7 @@ public final class BluetoothSap implements BluetoothProfile {
*
* @param device Bluetooth device
* @return priority of the device
+ * @hide
*/
public int getPriority(BluetoothDevice device) {
if (VDBG) log("getPriority(" + device + ")");
diff --git a/core/java/android/bluetooth/BluetoothSocket.java b/core/java/android/bluetooth/BluetoothSocket.java
index 5702d11..5cf2300 100644
--- a/core/java/android/bluetooth/BluetoothSocket.java
+++ b/core/java/android/bluetooth/BluetoothSocket.java
@@ -91,9 +91,13 @@ public final class BluetoothSocket implements Closeable {
public static final int MAX_RFCOMM_CHANNEL = 30;
/*package*/ static final int MAX_L2CAP_PACKAGE_SIZE = 0xFFFF;
- /** Keep TYPE_ fields in sync with BluetoothSocket.cpp */
+ /** RFCOMM socket */
public static final int TYPE_RFCOMM = 1;
+
+ /** SCO socket */
public static final int TYPE_SCO = 2;
+
+ /** L2CAP socket */
public static final int TYPE_L2CAP = 3;
/*package*/ static final int EBADFD = 77;
@@ -578,8 +582,8 @@ public final class BluetoothSocket implements Closeable {
}
/**
- * Get the type of the underlying connection
- * @return one of TYPE_
+ * Get the type of the underlying connection.
+ * @return one of {@link #TYPE_RFCOMM}, {@link #TYPE_SCO} or {@link #TYPE_L2CAP}
*/
public int getConnectionType() {
return mType;
diff --git a/core/java/android/bluetooth/le/ScanCallback.java b/core/java/android/bluetooth/le/ScanCallback.java
index 27b96bd..61b2e78 100644
--- a/core/java/android/bluetooth/le/ScanCallback.java
+++ b/core/java/android/bluetooth/le/ScanCallback.java
@@ -53,8 +53,10 @@ public abstract class ScanCallback {
/**
* Callback when a BLE advertisement has been found.
*
- * @param callbackType Determines how this callback was triggered. Could be of
- * {@link ScanSettings#CALLBACK_TYPE_ALL_MATCHES}
+ * @param callbackType Determines how this callback was triggered. Could be one of
+ * {@link ScanSettings#CALLBACK_TYPE_ALL_MATCHES},
+ * {@link ScanSettings#CALLBACK_TYPE_FIRST_MATCH} or
+ * {@link ScanSettings#CALLBACK_TYPE_MATCH_LOST}
* @param result A Bluetooth LE scan result.
*/
public void onScanResult(int callbackType, ScanResult result) {
diff --git a/core/java/android/bluetooth/le/ScanSettings.java b/core/java/android/bluetooth/le/ScanSettings.java
index dad486d..4eeb577 100644
--- a/core/java/android/bluetooth/le/ScanSettings.java
+++ b/core/java/android/bluetooth/le/ScanSettings.java
@@ -59,17 +59,13 @@ public final class ScanSettings implements Parcelable {
/**
* A result callback is only triggered for the first advertisement packet received that matches
* the filter criteria.
- * @hide
*/
- @SystemApi
public static final int CALLBACK_TYPE_FIRST_MATCH = 2;
/**
* Receive a callback when advertisements are no longer received from a device that has been
* previously reported by a first match callback.
- * @hide
*/
- @SystemApi
public static final int CALLBACK_TYPE_MATCH_LOST = 4;
@@ -78,21 +74,18 @@ public final class ScanSettings implements Parcelable {
*/
/**
* Match one advertisement per filter
- * @hide
*/
public static final int MATCH_NUM_ONE_ADVERTISEMENT = 1;
/**
* Match few advertisement per filter, depends on current capability and availibility of
* the resources in hw
- * @hide
*/
public static final int MATCH_NUM_FEW_ADVERTISEMENT = 2;
/**
* Match as many advertisement per filter as hw could allow, depends on current
* capability and availibility of the resources in hw
- * @hide
*/
public static final int MATCH_NUM_MAX_ADVERTISEMENT = 3;
@@ -100,14 +93,12 @@ public final class ScanSettings implements Parcelable {
/**
* In Aggressive mode, hw will determine a match sooner even with feeble signal strength
* and few number of sightings/match in a duration.
- * @hide
*/
public static final int MATCH_MODE_AGGRESSIVE = 1;
/**
* For sticky mode, higher threshold of signal strength and sightings is required
* before reporting by hw
- * @hide
*/
public static final int MATCH_MODE_STICKY = 2;
@@ -324,7 +315,6 @@ public final class ScanSettings implements Parcelable {
* {@link ScanSettings#MATCH_NUM_FEW_ADVERTISEMENT} or
* {@link ScanSettings#MATCH_NUM_MAX_ADVERTISEMENT}
* @throws IllegalArgumentException If the {@code matchMode} is invalid.
- * @hide
*/
public Builder setNumOfMatches(int numOfMatches) {
if (numOfMatches < MATCH_NUM_ONE_ADVERTISEMENT
@@ -342,7 +332,6 @@ public final class ScanSettings implements Parcelable {
* {@link ScanSettings#MATCH_MODE_AGGRESSIVE} or
* {@link ScanSettings#MATCH_MODE_STICKY}
* @throws IllegalArgumentException If the {@code matchMode} is invalid.
- * @hide
*/
public Builder setMatchMode(int matchMode) {
if (matchMode < MATCH_MODE_AGGRESSIVE
diff --git a/core/java/android/content/pm/ActivityInfo.java b/core/java/android/content/pm/ActivityInfo.java
index 16f6b1e..43cc63b 100644
--- a/core/java/android/content/pm/ActivityInfo.java
+++ b/core/java/android/content/pm/ActivityInfo.java
@@ -570,13 +570,16 @@ public class ActivityInfo extends ComponentInfo
Configuration.NATIVE_CONFIG_DENSITY, // DENSITY
Configuration.NATIVE_CONFIG_LAYOUTDIR, // LAYOUT DIRECTION
};
- /** @hide
+
+ /**
* Convert Java change bits to native.
+ *
+ * @hide
*/
public static int activityInfoConfigToNative(int input) {
int output = 0;
- for (int i=0; i<CONFIG_NATIVE_BITS.length; i++) {
- if ((input&(1<<i)) != 0) {
+ for (int i = 0; i < CONFIG_NATIVE_BITS.length; i++) {
+ if ((input & (1 << i)) != 0) {
output |= CONFIG_NATIVE_BITS[i];
}
}
@@ -584,6 +587,21 @@ public class ActivityInfo extends ComponentInfo
}
/**
+ * Convert native change bits to Java.
+ *
+ * @hide
+ */
+ public static int activityInfoConfigNativeToJava(int input) {
+ int output = 0;
+ for (int i = 0; i < CONFIG_NATIVE_BITS.length; i++) {
+ if ((input & CONFIG_NATIVE_BITS[i]) != 0) {
+ output |= (1 << i);
+ }
+ }
+ return output;
+ }
+
+ /**
* @hide
* Unfortunately some developers (OpenFeint I am looking at you) have
* compared the configChanges bit field against absolute values, so if we
diff --git a/core/java/android/content/pm/IPackageManager.aidl b/core/java/android/content/pm/IPackageManager.aidl
index 0b24594..94b0223 100644
--- a/core/java/android/content/pm/IPackageManager.aidl
+++ b/core/java/android/content/pm/IPackageManager.aidl
@@ -96,9 +96,9 @@ interface IPackageManager {
void removePermission(String name);
- boolean grantPermission(String packageName, String permissionName, int userId);
+ void grantPermission(String packageName, String permissionName, int userId);
- boolean revokePermission(String packageName, String permissionName, int userId);
+ void revokePermission(String packageName, String permissionName, int userId);
boolean isProtectedBroadcast(String actionName);
diff --git a/core/java/android/content/res/AssetManager.java b/core/java/android/content/res/AssetManager.java
index a176593..525059f 100644
--- a/core/java/android/content/res/AssetManager.java
+++ b/core/java/android/content/res/AssetManager.java
@@ -789,6 +789,7 @@ public final class AssetManager implements AutoCloseable {
TypedValue outValue,
boolean resolve);
/*package*/ native static final void dumpTheme(long theme, int priority, String tag, String prefix);
+ /*package*/ native static final int getThemeChangingConfigurations(long theme);
private native final long openXmlAssetNative(int cookie, String fileName);
diff --git a/core/java/android/content/res/Resources.java b/core/java/android/content/res/Resources.java
index 6e77e33..ae41b69 100644
--- a/core/java/android/content/res/Resources.java
+++ b/core/java/android/content/res/Resources.java
@@ -1731,6 +1731,19 @@ public class Resources {
}
/**
+ * Returns a bit mask of configuration changes that will impact this
+ * theme (and thus require completely reloading it).
+ *
+ * @return a bit mask of configuration changes, as defined by
+ * {@link ActivityInfo}
+ * @see ActivityInfo
+ */
+ public int getChangingConfigurations() {
+ final int nativeChangingConfig = AssetManager.getThemeChangingConfigurations(mTheme);
+ return ActivityInfo.activityInfoConfigNativeToJava(nativeChangingConfig);
+ }
+
+ /**
* Print contents of this theme out to the log. For debugging only.
*
* @param priority The log priority to use.
diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java
index 2d63e3f..d8c3361 100644
--- a/core/java/android/net/ConnectivityManager.java
+++ b/core/java/android/net/ConnectivityManager.java
@@ -2571,10 +2571,8 @@ public class ConnectivityManager {
* method assumes that the caller has previously called {@link #registerNetworkCallback} to
* listen for network changes.
*
- * @param network{@link Network} specifying which network you're interested.
+ * @param network {@link Network} specifying which network you're interested.
* @return {@code true} on success, {@code false} if the {@link Network} is no longer valid.
- *
- * @hide
*/
public boolean requestBandwidthUpdate(Network network) {
try {
diff --git a/core/java/android/os/AsyncTask.java b/core/java/android/os/AsyncTask.java
index 47e8e69..243ddf7 100644
--- a/core/java/android/os/AsyncTask.java
+++ b/core/java/android/os/AsyncTask.java
@@ -16,6 +16,9 @@
package android.os;
+import android.annotation.MainThread;
+import android.annotation.WorkerThread;
+
import java.util.ArrayDeque;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.Callable;
@@ -350,6 +353,7 @@ public abstract class AsyncTask<Params, Progress, Result> {
* @see #onPostExecute
* @see #publishProgress
*/
+ @WorkerThread
protected abstract Result doInBackground(Params... params);
/**
@@ -358,6 +362,7 @@ public abstract class AsyncTask<Params, Progress, Result> {
* @see #onPostExecute
* @see #doInBackground
*/
+ @MainThread
protected void onPreExecute() {
}
@@ -374,6 +379,7 @@ public abstract class AsyncTask<Params, Progress, Result> {
* @see #onCancelled(Object)
*/
@SuppressWarnings({"UnusedDeclaration"})
+ @MainThread
protected void onPostExecute(Result result) {
}
@@ -387,6 +393,7 @@ public abstract class AsyncTask<Params, Progress, Result> {
* @see #doInBackground
*/
@SuppressWarnings({"UnusedDeclaration"})
+ @MainThread
protected void onProgressUpdate(Progress... values) {
}
@@ -405,6 +412,7 @@ public abstract class AsyncTask<Params, Progress, Result> {
* @see #isCancelled()
*/
@SuppressWarnings({"UnusedParameters"})
+ @MainThread
protected void onCancelled(Result result) {
onCancelled();
}
@@ -421,6 +429,7 @@ public abstract class AsyncTask<Params, Progress, Result> {
* @see #cancel(boolean)
* @see #isCancelled()
*/
+ @MainThread
protected void onCancelled() {
}
@@ -535,6 +544,7 @@ public abstract class AsyncTask<Params, Progress, Result> {
* @see #executeOnExecutor(java.util.concurrent.Executor, Object[])
* @see #execute(Runnable)
*/
+ @MainThread
public final AsyncTask<Params, Progress, Result> execute(Params... params) {
return executeOnExecutor(sDefaultExecutor, params);
}
@@ -572,6 +582,7 @@ public abstract class AsyncTask<Params, Progress, Result> {
*
* @see #execute(Object[])
*/
+ @MainThread
public final AsyncTask<Params, Progress, Result> executeOnExecutor(Executor exec,
Params... params) {
if (mStatus != Status.PENDING) {
@@ -604,6 +615,7 @@ public abstract class AsyncTask<Params, Progress, Result> {
* @see #execute(Object[])
* @see #executeOnExecutor(java.util.concurrent.Executor, Object[])
*/
+ @MainThread
public static void execute(Runnable runnable) {
sDefaultExecutor.execute(runnable);
}
@@ -622,6 +634,7 @@ public abstract class AsyncTask<Params, Progress, Result> {
* @see #onProgressUpdate
* @see #doInBackground
*/
+ @WorkerThread
protected final void publishProgress(Progress... values) {
if (!isCancelled()) {
getHandler().obtainMessage(MESSAGE_POST_PROGRESS,
diff --git a/core/java/android/os/Bundle.java b/core/java/android/os/Bundle.java
index 5e9b8c1..74699fd 100644
--- a/core/java/android/os/Bundle.java
+++ b/core/java/android/os/Bundle.java
@@ -211,8 +211,9 @@ public final class Bundle extends BaseBundle implements Cloneable, Parcelable {
} else if (obj instanceof Parcelable[]) {
Parcelable[] array = (Parcelable[]) obj;
for (int n = array.length - 1; n >= 0; n--) {
- if ((array[n].describeContents()
- & Parcelable.CONTENTS_FILE_DESCRIPTOR) != 0) {
+ Parcelable p = array[n];
+ if (p != null && ((p.describeContents()
+ & Parcelable.CONTENTS_FILE_DESCRIPTOR) != 0)) {
fdFound = true;
break;
}
@@ -221,7 +222,8 @@ public final class Bundle extends BaseBundle implements Cloneable, Parcelable {
SparseArray<? extends Parcelable> array =
(SparseArray<? extends Parcelable>) obj;
for (int n = array.size() - 1; n >= 0; n--) {
- if ((array.valueAt(n).describeContents()
+ Parcelable p = array.valueAt(n);
+ if (p != null && (p.describeContents()
& Parcelable.CONTENTS_FILE_DESCRIPTOR) != 0) {
fdFound = true;
break;
diff --git a/core/java/android/os/storage/StorageManager.java b/core/java/android/os/storage/StorageManager.java
index 50e7d1c..3fdabee 100644
--- a/core/java/android/os/storage/StorageManager.java
+++ b/core/java/android/os/storage/StorageManager.java
@@ -584,7 +584,7 @@ public class StorageManager {
// Nickname always takes precedence when defined
if (!TextUtils.isEmpty(vol.fsUuid)) {
final VolumeRecord rec = findRecordByUuid(vol.fsUuid);
- if (!TextUtils.isEmpty(rec.nickname)) {
+ if (rec != null && !TextUtils.isEmpty(rec.nickname)) {
return rec.nickname;
}
}
diff --git a/core/java/android/preference/GenericInflater.java b/core/java/android/preference/GenericInflater.java
index 918933b..3319e64 100644
--- a/core/java/android/preference/GenericInflater.java
+++ b/core/java/android/preference/GenericInflater.java
@@ -376,6 +376,7 @@ abstract class GenericInflater<T, P extends GenericInflater.Parent> {
Class clazz = mContext.getClassLoader().loadClass(
prefix != null ? (prefix + name) : name);
constructor = clazz.getConstructor(mConstructorSignature);
+ constructor.setAccessible(true);
sConstructorMap.put(name, constructor);
}
diff --git a/core/java/android/provider/ContactsContract.java b/core/java/android/provider/ContactsContract.java
index 396cf19..e07e846 100644
--- a/core/java/android/provider/ContactsContract.java
+++ b/core/java/android/provider/ContactsContract.java
@@ -9062,5 +9062,15 @@ public final class ContactsContract {
*/
public static final Uri CONTENT_URI = Uri.withAppendedPath(METADATA_AUTHORITY_URI,
"metadata_sync");
+
+ /**
+ * The MIME type of {@link #CONTENT_URI} providing a directory of contact metadata
+ */
+ public static final String CONTENT_TYPE = "vnd.android.cursor.dir/contact_metadata";
+
+ /**
+ * The MIME type of a {@link #CONTENT_URI} subdirectory of a single contact metadata.
+ */
+ public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/contact_metadata";
}
}
diff --git a/core/java/android/service/carrier/CarrierMessagingService.java b/core/java/android/service/carrier/CarrierMessagingService.java
index 0592a84..d7bf10c 100644
--- a/core/java/android/service/carrier/CarrierMessagingService.java
+++ b/core/java/android/service/carrier/CarrierMessagingService.java
@@ -80,6 +80,11 @@ public abstract class CarrierMessagingService extends Service {
*/
public static final int DOWNLOAD_STATUS_ERROR = 2;
+ /**
+ * Flag to request SMS delivery status report.
+ */
+ public static final int SEND_FLAG_REQUEST_DELIVERY_STATUS = 1;
+
private final ICarrierMessagingWrapper mWrapper = new ICarrierMessagingWrapper();
/**
@@ -103,12 +108,14 @@ public abstract class CarrierMessagingService extends Service {
/**
* Override this method to intercept text SMSs sent from the device.
+ * @deprecated Override {@link #onSendTextSms} below instead.
*
* @param text the text to send
* @param subId SMS subscription ID of the SIM
* @param destAddress phone number of the recipient of the message
* @param callback result callback. Call with a {@link SendSmsResult}.
*/
+ @Deprecated
public void onSendTextSms(
@NonNull String text, int subId, @NonNull String destAddress,
@NonNull ResultCallback<SendSmsResult> callback) {
@@ -120,7 +127,25 @@ public abstract class CarrierMessagingService extends Service {
}
/**
+ * Override this method to intercept text SMSs sent from the device.
+ *
+ * @param text the text to send
+ * @param subId SMS subscription ID of the SIM
+ * @param destAddress phone number of the recipient of the message
+ * @param sendSmsFlag Flag for sending SMS. Acceptable values are 0 and
+ * {@link #SEND_FLAG_REQUEST_DELIVERY_STATUS}.
+ * @param callback result callback. Call with a {@link SendSmsResult}.
+ */
+ public void onSendTextSms(
+ @NonNull String text, int subId, @NonNull String destAddress,
+ int sendSmsFlag, @NonNull ResultCallback<SendSmsResult> callback) {
+ // optional
+ onSendTextSms(text, subId, destAddress, callback);
+ }
+
+ /**
* Override this method to intercept binary SMSs sent from the device.
+ * @deprecated Override {@link #onSendDataSms} below instead.
*
* @param data the binary content
* @param subId SMS subscription ID of the SIM
@@ -128,6 +153,7 @@ public abstract class CarrierMessagingService extends Service {
* @param destPort the destination port
* @param callback result callback. Call with a {@link SendSmsResult}.
*/
+ @Deprecated
public void onSendDataSms(@NonNull byte[] data, int subId,
@NonNull String destAddress, int destPort,
@NonNull ResultCallback<SendSmsResult> callback) {
@@ -139,13 +165,33 @@ public abstract class CarrierMessagingService extends Service {
}
/**
+ * Override this method to intercept binary SMSs sent from the device.
+ *
+ * @param data the binary content
+ * @param subId SMS subscription ID of the SIM
+ * @param destAddress phone number of the recipient of the message
+ * @param destPort the destination port
+ * @param sendSmsFlag Flag for sending SMS. Acceptable values are 0 and
+ * {@link #SEND_FLAG_REQUEST_DELIVERY_STATUS}.
+ * @param callback result callback. Call with a {@link SendSmsResult}.
+ */
+ public void onSendDataSms(@NonNull byte[] data, int subId,
+ @NonNull String destAddress, int destPort, int sendSmsFlag,
+ @NonNull ResultCallback<SendSmsResult> callback) {
+ // optional
+ onSendDataSms(data, subId, destAddress, destPort, callback);
+ }
+
+ /**
* Override this method to intercept long SMSs sent from the device.
+ * @deprecated Override {@link #onSendMultipartTextSms} below instead.
*
* @param parts a {@link List} of the message parts
* @param subId SMS subscription ID of the SIM
* @param destAddress phone number of the recipient of the message
* @param callback result callback. Call with a {@link SendMultipartSmsResult}.
*/
+ @Deprecated
public void onSendMultipartTextSms(@NonNull List<String> parts,
int subId, @NonNull String destAddress,
@NonNull ResultCallback<SendMultipartSmsResult> callback) {
@@ -158,6 +204,23 @@ public abstract class CarrierMessagingService extends Service {
}
/**
+ * Override this method to intercept long SMSs sent from the device.
+ *
+ * @param parts a {@link List} of the message parts
+ * @param subId SMS subscription ID of the SIM
+ * @param destAddress phone number of the recipient of the message
+ * @param sendSmsFlag Flag for sending SMS. Acceptable values are 0 and
+ * {@link #SEND_FLAG_REQUEST_DELIVERY_STATUS}.
+ * @param callback result callback. Call with a {@link SendMultipartSmsResult}.
+ */
+ public void onSendMultipartTextSms(@NonNull List<String> parts,
+ int subId, @NonNull String destAddress, int sendSmsFlag,
+ @NonNull ResultCallback<SendMultipartSmsResult> callback) {
+ // optional
+ onSendMultipartTextSms(parts, subId, destAddress, callback);
+ }
+
+ /**
* Override this method to intercept MMSs sent from the device.
*
* @param pduUri the content provider URI of the PDU to send
@@ -355,8 +418,9 @@ public abstract class CarrierMessagingService extends Service {
@Override
public void sendTextSms(String text, int subId, String destAddress,
- final ICarrierMessagingCallback callback) {
- onSendTextSms(text, subId, destAddress, new ResultCallback<SendSmsResult>() {
+ int sendSmsFlag, final ICarrierMessagingCallback callback) {
+ onSendTextSms(text, subId, destAddress, sendSmsFlag,
+ new ResultCallback<SendSmsResult>() {
@Override
public void onReceiveResult(final SendSmsResult result) throws RemoteException {
callback.onSendSmsComplete(result.getSendStatus(), result.getMessageRef());
@@ -366,8 +430,9 @@ public abstract class CarrierMessagingService extends Service {
@Override
public void sendDataSms(byte[] data, int subId, String destAddress, int destPort,
- final ICarrierMessagingCallback callback) {
- onSendDataSms(data, subId, destAddress, destPort, new ResultCallback<SendSmsResult>() {
+ int sendSmsFlag, final ICarrierMessagingCallback callback) {
+ onSendDataSms(data, subId, destAddress, destPort, sendSmsFlag,
+ new ResultCallback<SendSmsResult>() {
@Override
public void onReceiveResult(final SendSmsResult result) throws RemoteException {
callback.onSendSmsComplete(result.getSendStatus(), result.getMessageRef());
@@ -377,8 +442,8 @@ public abstract class CarrierMessagingService extends Service {
@Override
public void sendMultipartTextSms(List<String> parts, int subId, String destAddress,
- final ICarrierMessagingCallback callback) {
- onSendMultipartTextSms(parts, subId, destAddress,
+ int sendSmsFlag, final ICarrierMessagingCallback callback) {
+ onSendMultipartTextSms(parts, subId, destAddress, sendSmsFlag,
new ResultCallback<SendMultipartSmsResult>() {
@Override
public void onReceiveResult(final SendMultipartSmsResult result)
diff --git a/core/java/android/service/carrier/ICarrierMessagingService.aidl b/core/java/android/service/carrier/ICarrierMessagingService.aidl
index 40a9047..2d96c3d 100644
--- a/core/java/android/service/carrier/ICarrierMessagingService.aidl
+++ b/core/java/android/service/carrier/ICarrierMessagingService.aidl
@@ -48,9 +48,10 @@ oneway interface ICarrierMessagingService {
* @param text the text to send
* @param subId SMS subscription ID of the SIM
* @param destAddress phone number of the recipient of the message
+ * @param sendSmsFlag flag for sending SMS
* @param callback the callback to notify upon completion
*/
- void sendTextSms(String text, int subId, String destAddress,
+ void sendTextSms(String text, int subId, String destAddress, int sendSmsFlag,
in ICarrierMessagingCallback callback);
/**
@@ -62,10 +63,11 @@ oneway interface ICarrierMessagingService {
* @param subId SMS subscription ID of the SIM
* @param destAddress phone number of the recipient of the message
* @param destPort port number of the recipient of the message
+ * @param sendSmsFlag flag for sending SMS
* @param callback the callback to notify upon completion
*/
void sendDataSms(in byte[] data, int subId, String destAddress, int destPort,
- in ICarrierMessagingCallback callback);
+ int sendSmsFlag, in ICarrierMessagingCallback callback);
/**
* Request sending a new multi-part text SMS from the device.
@@ -75,10 +77,11 @@ oneway interface ICarrierMessagingService {
* @param parts the parts of the multi-part text SMS to send
* @param subId SMS subscription ID of the SIM
* @param destAddress phone number of the recipient of the message
+ * @param sendSmsFlag flag for sending SMS
* @param callback the callback to notify upon completion
*/
void sendMultipartTextSms(in List<String> parts, int subId, String destAddress,
- in ICarrierMessagingCallback callback);
+ int sendSmsFlag, in ICarrierMessagingCallback callback);
/**
* Request sending a new MMS PDU from the device.
diff --git a/core/java/android/service/notification/ZenModeConfig.java b/core/java/android/service/notification/ZenModeConfig.java
index f09f4d2..26bd10f 100644
--- a/core/java/android/service/notification/ZenModeConfig.java
+++ b/core/java/android/service/notification/ZenModeConfig.java
@@ -55,6 +55,7 @@ public class ZenModeConfig implements Parcelable {
public static final int SOURCE_CONTACT = 1;
public static final int SOURCE_STAR = 2;
public static final int MAX_SOURCE = SOURCE_STAR;
+ private static final int DEFAULT_SOURCE = SOURCE_CONTACT;
public static final int[] ALL_DAYS = { Calendar.SUNDAY, Calendar.MONDAY, Calendar.TUESDAY,
Calendar.WEDNESDAY, Calendar.THURSDAY, Calendar.FRIDAY, Calendar.SATURDAY };
@@ -67,6 +68,8 @@ public class ZenModeConfig implements Parcelable {
private static final int MINUTES_MS = 60 * SECONDS_MS;
private static final int ZERO_VALUE_MS = 10 * SECONDS_MS;
+ private static final boolean DEFAULT_ALLOW_CALLS = true;
+ private static final boolean DEFAULT_ALLOW_MESSAGES = false;
private static final boolean DEFAULT_ALLOW_REMINDERS = true;
private static final boolean DEFAULT_ALLOW_EVENTS = true;
private static final boolean DEFAULT_ALLOW_REPEAT_CALLERS = false;
@@ -79,6 +82,8 @@ public class ZenModeConfig implements Parcelable {
private static final String ALLOW_ATT_REPEAT_CALLERS = "repeatCallers";
private static final String ALLOW_ATT_MESSAGES = "messages";
private static final String ALLOW_ATT_FROM = "from";
+ private static final String ALLOW_ATT_CALLS_FROM = "callsFrom";
+ private static final String ALLOW_ATT_MESSAGES_FROM = "messagesFrom";
private static final String ALLOW_ATT_REMINDERS = "reminders";
private static final String ALLOW_ATT_EVENTS = "events";
@@ -103,12 +108,13 @@ public class ZenModeConfig implements Parcelable {
private static final String RULE_ATT_ZEN = "zen";
private static final String RULE_ATT_CONDITION_ID = "conditionId";
- public boolean allowCalls;
+ public boolean allowCalls = DEFAULT_ALLOW_CALLS;
public boolean allowRepeatCallers = DEFAULT_ALLOW_REPEAT_CALLERS;
- public boolean allowMessages;
+ public boolean allowMessages = DEFAULT_ALLOW_MESSAGES;
public boolean allowReminders = DEFAULT_ALLOW_REMINDERS;
public boolean allowEvents = DEFAULT_ALLOW_EVENTS;
- public int allowFrom = SOURCE_ANYONE;
+ public int allowCallsFrom = DEFAULT_SOURCE;
+ public int allowMessagesFrom = DEFAULT_SOURCE;
public ZenRule manualRule;
public ArrayMap<String, ZenRule> automaticRules = new ArrayMap<>();
@@ -121,7 +127,8 @@ public class ZenModeConfig implements Parcelable {
allowMessages = source.readInt() == 1;
allowReminders = source.readInt() == 1;
allowEvents = source.readInt() == 1;
- allowFrom = source.readInt();
+ allowCallsFrom = source.readInt();
+ allowMessagesFrom = source.readInt();
manualRule = source.readParcelable(null);
final int len = source.readInt();
if (len > 0) {
@@ -142,7 +149,8 @@ public class ZenModeConfig implements Parcelable {
dest.writeInt(allowMessages ? 1 : 0);
dest.writeInt(allowReminders ? 1 : 0);
dest.writeInt(allowEvents ? 1 : 0);
- dest.writeInt(allowFrom);
+ dest.writeInt(allowCallsFrom);
+ dest.writeInt(allowMessagesFrom);
dest.writeParcelable(manualRule, 0);
if (!automaticRules.isEmpty()) {
final int len = automaticRules.size();
@@ -166,7 +174,8 @@ public class ZenModeConfig implements Parcelable {
.append("allowCalls=").append(allowCalls)
.append(",allowRepeatCallers=").append(allowRepeatCallers)
.append(",allowMessages=").append(allowMessages)
- .append(",allowFrom=").append(sourceToString(allowFrom))
+ .append(",allowCallsFrom=").append(sourceToString(allowCallsFrom))
+ .append(",allowMessagesFrom=").append(sourceToString(allowMessagesFrom))
.append(",allowReminders=").append(allowReminders)
.append(",allowEvents=").append(allowEvents)
.append(",automaticRules=").append(automaticRules)
@@ -234,7 +243,8 @@ public class ZenModeConfig implements Parcelable {
return other.allowCalls == allowCalls
&& other.allowRepeatCallers == allowRepeatCallers
&& other.allowMessages == allowMessages
- && other.allowFrom == allowFrom
+ && other.allowCallsFrom == allowCallsFrom
+ && other.allowMessagesFrom == allowMessagesFrom
&& other.allowReminders == allowReminders
&& other.allowEvents == allowEvents
&& Objects.equals(other.automaticRules, automaticRules)
@@ -243,8 +253,8 @@ public class ZenModeConfig implements Parcelable {
@Override
public int hashCode() {
- return Objects.hash(allowCalls, allowRepeatCallers, allowMessages, allowFrom,
- allowReminders, allowEvents, automaticRules, manualRule);
+ return Objects.hash(allowCalls, allowRepeatCallers, allowMessages, allowCallsFrom,
+ allowMessagesFrom, allowReminders, allowEvents, automaticRules, manualRule);
}
private static String toDayList(int[] days) {
@@ -314,9 +324,19 @@ public class ZenModeConfig implements Parcelable {
rt.allowReminders = safeBoolean(parser, ALLOW_ATT_REMINDERS,
DEFAULT_ALLOW_REMINDERS);
rt.allowEvents = safeBoolean(parser, ALLOW_ATT_EVENTS, DEFAULT_ALLOW_EVENTS);
- rt.allowFrom = safeInt(parser, ALLOW_ATT_FROM, SOURCE_ANYONE);
- if (rt.allowFrom < SOURCE_ANYONE || rt.allowFrom > MAX_SOURCE) {
- throw new IndexOutOfBoundsException("bad source in config:" + rt.allowFrom);
+ final int from = safeInt(parser, ALLOW_ATT_FROM, -1);
+ final int callsFrom = safeInt(parser, ALLOW_ATT_CALLS_FROM, -1);
+ final int messagesFrom = safeInt(parser, ALLOW_ATT_MESSAGES_FROM, -1);
+ if (isValidSource(callsFrom) && isValidSource(messagesFrom)) {
+ rt.allowCallsFrom = callsFrom;
+ rt.allowMessagesFrom = messagesFrom;
+ } else if (isValidSource(from)) {
+ Slog.i(TAG, "Migrating existing shared 'from': " + sourceToString(from));
+ rt.allowCallsFrom = from;
+ rt.allowMessagesFrom = from;
+ } else {
+ rt.allowCallsFrom = DEFAULT_SOURCE;
+ rt.allowMessagesFrom = DEFAULT_SOURCE;
}
} else if (MANUAL_TAG.equals(tag)) {
rt.manualRule = readRuleXml(parser, false /*conditionRequired*/);
@@ -342,7 +362,8 @@ public class ZenModeConfig implements Parcelable {
out.attribute(null, ALLOW_ATT_MESSAGES, Boolean.toString(allowMessages));
out.attribute(null, ALLOW_ATT_REMINDERS, Boolean.toString(allowReminders));
out.attribute(null, ALLOW_ATT_EVENTS, Boolean.toString(allowEvents));
- out.attribute(null, ALLOW_ATT_FROM, Integer.toString(allowFrom));
+ out.attribute(null, ALLOW_ATT_CALLS_FROM, Integer.toString(allowCallsFrom));
+ out.attribute(null, ALLOW_ATT_MESSAGES_FROM, Integer.toString(allowMessagesFrom));
out.endTag(null, ALLOW_TAG);
if (manualRule != null) {
@@ -432,6 +453,10 @@ public class ZenModeConfig implements Parcelable {
return val >= 0 && val < 60;
}
+ private static boolean isValidSource(int source) {
+ return source >= SOURCE_ANYONE && source <= MAX_SOURCE;
+ }
+
private static boolean safeBoolean(XmlPullParser parser, String att, boolean defValue) {
final String val = parser.getAttributeValue(null, att);
if (TextUtils.isEmpty(val)) return defValue;
@@ -494,7 +519,8 @@ public class ZenModeConfig implements Parcelable {
public Policy toNotificationPolicy() {
int priorityCategories = 0;
- int prioritySenders = Policy.PRIORITY_SENDERS_ANY;
+ int priorityCallSenders = Policy.PRIORITY_SENDERS_CONTACTS;
+ int priorityMessageSenders = Policy.PRIORITY_SENDERS_CONTACTS;
if (allowCalls) {
priorityCategories |= Policy.PRIORITY_CATEGORY_CALLS;
}
@@ -510,18 +536,27 @@ public class ZenModeConfig implements Parcelable {
if (allowRepeatCallers) {
priorityCategories |= Policy.PRIORITY_CATEGORY_REPEAT_CALLERS;
}
- switch (allowFrom) {
- case SOURCE_ANYONE:
- prioritySenders = Policy.PRIORITY_SENDERS_ANY;
- break;
- case SOURCE_CONTACT:
- prioritySenders = Policy.PRIORITY_SENDERS_CONTACTS;
- break;
- case SOURCE_STAR:
- prioritySenders = Policy.PRIORITY_SENDERS_STARRED;
- break;
+ priorityCallSenders = sourceToPrioritySenders(allowCallsFrom, priorityCallSenders);
+ priorityMessageSenders = sourceToPrioritySenders(allowMessagesFrom, priorityMessageSenders);
+ return new Policy(priorityCategories, priorityCallSenders);
+ }
+
+ private static int sourceToPrioritySenders(int source, int def) {
+ switch (source) {
+ case SOURCE_ANYONE: return Policy.PRIORITY_SENDERS_ANY;
+ case SOURCE_CONTACT: return Policy.PRIORITY_SENDERS_CONTACTS;
+ case SOURCE_STAR: return Policy.PRIORITY_SENDERS_STARRED;
+ default: return def;
+ }
+ }
+
+ private static int prioritySendersToSource(int prioritySenders, int def) {
+ switch (prioritySenders) {
+ case Policy.PRIORITY_SENDERS_CONTACTS: return SOURCE_CONTACT;
+ case Policy.PRIORITY_SENDERS_STARRED: return SOURCE_STAR;
+ case Policy.PRIORITY_SENDERS_ANY: return SOURCE_ANYONE;
+ default: return def;
}
- return new Policy(priorityCategories, prioritySenders);
}
public void applyNotificationPolicy(Policy policy) {
@@ -532,17 +567,7 @@ public class ZenModeConfig implements Parcelable {
allowReminders = (policy.priorityCategories & Policy.PRIORITY_CATEGORY_REMINDERS) != 0;
allowRepeatCallers = (policy.priorityCategories & Policy.PRIORITY_CATEGORY_REPEAT_CALLERS)
!= 0;
- switch (policy.prioritySenders) {
- case Policy.PRIORITY_SENDERS_CONTACTS:
- allowFrom = SOURCE_CONTACT;
- break;
- case Policy.PRIORITY_SENDERS_STARRED:
- allowFrom = SOURCE_STAR;
- break;
- default:
- allowFrom = SOURCE_ANYONE;
- break;
- }
+ allowCallsFrom = prioritySendersToSource(policy.prioritySenders, allowCallsFrom);
}
public static Condition toTimeCondition(Context context, int minutesFromNow, int userHandle) {
@@ -692,7 +717,6 @@ public class ZenModeConfig implements Parcelable {
.authority(SYSTEM_AUTHORITY)
.appendPath(EVENT_PATH)
.appendQueryParameter("calendar", Long.toString(event.calendar))
- .appendQueryParameter("attendance", Integer.toString(event.attendance))
.appendQueryParameter("reply", Integer.toString(event.reply))
.build();
}
@@ -710,22 +734,16 @@ public class ZenModeConfig implements Parcelable {
if (!isEvent) return null;
final EventInfo rt = new EventInfo();
rt.calendar = tryParseLong(conditionId.getQueryParameter("calendar"), 0L);
- rt.attendance = tryParseInt(conditionId.getQueryParameter("attendance"), 0);
rt.reply = tryParseInt(conditionId.getQueryParameter("reply"), 0);
return rt;
}
public static class EventInfo {
- public static final int ATTENDANCE_REQUIRED_OR_OPTIONAL = 0;
- public static final int ATTENDANCE_REQUIRED = 1;
- public static final int ATTENDANCE_OPTIONAL = 2;
-
- public static final int REPLY_ANY = 0;
- public static final int REPLY_ANY_EXCEPT_NO = 1;
+ public static final int REPLY_ANY_EXCEPT_NO = 0;
+ public static final int REPLY_YES_OR_MAYBE = 1;
public static final int REPLY_YES = 2;
public long calendar; // CalendarContract.Calendars._ID, or 0 for any
- public int attendance;
public int reply;
@Override
@@ -738,14 +756,12 @@ public class ZenModeConfig implements Parcelable {
if (!(o instanceof EventInfo)) return false;
final EventInfo other = (EventInfo) o;
return calendar == other.calendar
- && attendance == other.attendance
&& reply == other.reply;
}
public EventInfo copy() {
final EventInfo rt = new EventInfo();
rt.calendar = calendar;
- rt.attendance = attendance;
rt.reply = reply;
return rt;
}
diff --git a/core/java/android/service/voice/IVoiceInteractionService.aidl b/core/java/android/service/voice/IVoiceInteractionService.aidl
index e8265a2..e3d68a6 100644
--- a/core/java/android/service/voice/IVoiceInteractionService.aidl
+++ b/core/java/android/service/voice/IVoiceInteractionService.aidl
@@ -23,4 +23,5 @@ oneway interface IVoiceInteractionService {
void ready();
void soundModelsChanged();
void shutdown();
+ void launchVoiceAssistFromKeyguard();
}
diff --git a/core/java/android/service/voice/VoiceInteractionService.java b/core/java/android/service/voice/VoiceInteractionService.java
index fee0c75..8c89ddb 100644
--- a/core/java/android/service/voice/VoiceInteractionService.java
+++ b/core/java/android/service/voice/VoiceInteractionService.java
@@ -98,6 +98,10 @@ public class VoiceInteractionService extends Service {
@Override public void soundModelsChanged() {
mHandler.sendEmptyMessage(MSG_SOUND_MODELS_CHANGED);
}
+ @Override
+ public void launchVoiceAssistFromKeyguard() throws RemoteException {
+ mHandler.sendEmptyMessage(MSG_LAUNCH_VOICE_ASSIST_FROM_KEYGUARD);
+ }
};
MyHandler mHandler;
@@ -113,6 +117,7 @@ public class VoiceInteractionService extends Service {
static final int MSG_READY = 1;
static final int MSG_SHUTDOWN = 2;
static final int MSG_SOUND_MODELS_CHANGED = 3;
+ static final int MSG_LAUNCH_VOICE_ASSIST_FROM_KEYGUARD = 4;
class MyHandler extends Handler {
@Override
@@ -127,6 +132,9 @@ public class VoiceInteractionService extends Service {
case MSG_SOUND_MODELS_CHANGED:
onSoundModelsChangedInternal();
break;
+ case MSG_LAUNCH_VOICE_ASSIST_FROM_KEYGUARD:
+ onLaunchVoiceAssistFromKeyguard();
+ break;
default:
super.handleMessage(msg);
}
@@ -134,6 +142,19 @@ public class VoiceInteractionService extends Service {
}
/**
+ * Called when a user has activated an affordance to launch voice assist from the Keyguard.
+ *
+ * <p>This method will only be called if the VoiceInteractionService has set
+ * {@link android.R.attr#supportsLaunchVoiceAssistFromKeyguard} and the Keyguard is showing.</p>
+ *
+ * <p>A valid implementation must start a new activity that should use {@link
+ * android.view.WindowManager.LayoutParams#FLAG_SHOW_WHEN_LOCKED} to display
+ * on top of the lock screen.</p>
+ */
+ public void onLaunchVoiceAssistFromKeyguard() {
+ }
+
+ /**
* Check whether the given service component is the currently active
* VoiceInteractionService.
*/
diff --git a/core/java/android/service/voice/VoiceInteractionServiceInfo.java b/core/java/android/service/voice/VoiceInteractionServiceInfo.java
index 997d586..463eb5b 100644
--- a/core/java/android/service/voice/VoiceInteractionServiceInfo.java
+++ b/core/java/android/service/voice/VoiceInteractionServiceInfo.java
@@ -44,6 +44,7 @@ public class VoiceInteractionServiceInfo {
private String mRecognitionService;
private String mSettingsActivity;
private boolean mSupportsAssist;
+ private boolean mSupportsLaunchFromKeyguard;
public VoiceInteractionServiceInfo(PackageManager pm, ComponentName comp)
throws PackageManager.NameNotFoundException {
@@ -98,6 +99,9 @@ public class VoiceInteractionServiceInfo {
mSupportsAssist = array.getBoolean(
com.android.internal.R.styleable.VoiceInteractionService_supportsAssist,
false);
+ mSupportsLaunchFromKeyguard = array.getBoolean(com.android.internal.
+ R.styleable.VoiceInteractionService_supportsLaunchVoiceAssistFromKeyguard,
+ false);
array.recycle();
if (mSessionService == null) {
mParseError = "No sessionService specified";
@@ -148,4 +152,8 @@ public class VoiceInteractionServiceInfo {
public boolean getSupportsAssist() {
return mSupportsAssist;
}
+
+ public boolean getSupportsLaunchFromKeyguard() {
+ return mSupportsLaunchFromKeyguard;
+ }
}
diff --git a/core/java/android/text/Html.java b/core/java/android/text/Html.java
index 7bebbfb..a55a08c 100644
--- a/core/java/android/text/Html.java
+++ b/core/java/android/text/Html.java
@@ -278,7 +278,7 @@ public class Html {
if (style[j] instanceof TypefaceSpan) {
String s = ((TypefaceSpan) style[j]).getFamily();
- if (s.equals("monospace")) {
+ if ("monospace".equals(s)) {
out.append("<tt>");
}
}
diff --git a/core/java/android/transition/Transition.java b/core/java/android/transition/Transition.java
index c942042..ebc2aac 100644
--- a/core/java/android/transition/Transition.java
+++ b/core/java/android/transition/Transition.java
@@ -792,6 +792,9 @@ public abstract class Transition implements Cloneable {
* views are ignored and only the ids are used).
*/
boolean isValidTarget(View target) {
+ if (target == null) {
+ return false;
+ }
int targetId = target.getId();
if (mTargetIdExcludes != null && mTargetIdExcludes.contains(targetId)) {
return false;
diff --git a/core/java/android/transition/TransitionInflater.java b/core/java/android/transition/TransitionInflater.java
index ca37d49..cbf76bc 100644
--- a/core/java/android/transition/TransitionInflater.java
+++ b/core/java/android/transition/TransitionInflater.java
@@ -211,10 +211,10 @@ public class TransitionInflater {
.asSubclass(expectedType);
if (c != null) {
constructor = c.getConstructor(sConstructorSignature);
+ constructor.setAccessible(true);
sConstructors.put(className, constructor);
}
}
- constructor.setAccessible(true);
return constructor.newInstance(mContext, attrs);
}
} catch (InstantiationException e) {
diff --git a/core/java/android/transition/Visibility.java b/core/java/android/transition/Visibility.java
index cd68fd1..ed7fd86 100644
--- a/core/java/android/transition/Visibility.java
+++ b/core/java/android/transition/Visibility.java
@@ -19,12 +19,17 @@ package android.transition;
import com.android.internal.R;
import android.animation.Animator;
+import android.animation.Animator.AnimatorListener;
+import android.animation.Animator.AnimatorPauseListener;
import android.animation.AnimatorListenerAdapter;
import android.content.Context;
import android.content.res.TypedArray;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;
+import android.view.animation.Animation;
+import android.view.animation.Animation.AnimationListener;
+
/**
* This transition tracks changes to the visibility of target views in the
* start and end scenes. Visibility is determined not just by the
@@ -286,6 +291,12 @@ public abstract class Visibility extends Transition {
return null;
}
}
+ final boolean isForcedVisibility = mForcedStartVisibility != -1 ||
+ mForcedEndVisibility != -1;
+ if (isForcedVisibility) {
+ // Make sure that we reverse the effect of onDisappear's setTransitionAlpha(0)
+ endValues.view.setTransitionAlpha(1);
+ }
return onAppear(sceneRoot, endValues.view, startValues, endValues);
}
@@ -418,9 +429,9 @@ public abstract class Visibility extends Transition {
sceneRoot.getOverlay().remove(overlayView);
} else {
final View finalOverlayView = overlayView;
- animator.addListener(new AnimatorListenerAdapter() {
+ addListener(new TransitionListenerAdapter() {
@Override
- public void onAnimationEnd(Animator animation) {
+ public void onTransitionEnd(Transition transition) {
finalSceneRoot.getOverlay().remove(finalOverlayView);
}
});
@@ -438,40 +449,10 @@ public abstract class Visibility extends Transition {
}
Animator animator = onDisappear(sceneRoot, viewToKeep, startValues, endValues);
if (animator != null) {
- final View finalViewToKeep = viewToKeep;
- animator.addListener(new AnimatorListenerAdapter() {
- boolean mCanceled = false;
-
- @Override
- public void onAnimationPause(Animator animation) {
- if (!mCanceled && !isForcedVisibility) {
- finalViewToKeep.setVisibility(finalVisibility);
- }
- }
-
- @Override
- public void onAnimationResume(Animator animation) {
- if (!mCanceled && !isForcedVisibility) {
- finalViewToKeep.setVisibility(View.VISIBLE);
- }
- }
-
- @Override
- public void onAnimationCancel(Animator animation) {
- mCanceled = true;
- }
-
- @Override
- public void onAnimationEnd(Animator animation) {
- if (!mCanceled) {
- if (isForcedVisibility) {
- finalViewToKeep.setTransitionAlpha(0);
- } else {
- finalViewToKeep.setVisibility(finalVisibility);
- }
- }
- }
- });
+ DisappearListener disappearListener = new DisappearListener(viewToKeep,
+ finalVisibility, isForcedVisibility);
+ animator.addListener(disappearListener);
+ addListener(disappearListener);
} else if (!isForcedVisibility) {
viewToKeep.setVisibility(originalVisibility);
}
@@ -517,4 +498,68 @@ public abstract class Visibility extends Transition {
TransitionValues endValues) {
return null;
}
+
+ private static class DisappearListener
+ extends TransitionListenerAdapter implements AnimatorListener, AnimatorPauseListener {
+ private final boolean mIsForcedVisibility;
+ private final View mView;
+ private final int mFinalVisibility;
+
+ boolean mCanceled = false;
+
+ public DisappearListener(View view, int finalVisibility, boolean isForcedVisibility) {
+ this.mView = view;
+ this.mIsForcedVisibility = isForcedVisibility;
+ this.mFinalVisibility = finalVisibility;
+ }
+
+ @Override
+ public void onAnimationPause(Animator animation) {
+ if (!mCanceled && !mIsForcedVisibility) {
+ mView.setVisibility(mFinalVisibility);
+ }
+ }
+
+ @Override
+ public void onAnimationResume(Animator animation) {
+ if (!mCanceled && !mIsForcedVisibility) {
+ mView.setVisibility(View.VISIBLE);
+ }
+ }
+
+ @Override
+ public void onAnimationCancel(Animator animation) {
+ mCanceled = true;
+ }
+
+ @Override
+ public void onAnimationRepeat(Animator animation) {
+
+ }
+
+ @Override
+ public void onAnimationStart(Animator animation) {
+
+ }
+
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ hideViewWhenNotCanceled();
+ }
+
+ @Override
+ public void onTransitionEnd(Transition transition) {
+ hideViewWhenNotCanceled();
+ }
+
+ private void hideViewWhenNotCanceled() {
+ if (!mCanceled) {
+ if (mIsForcedVisibility) {
+ mView.setTransitionAlpha(0);
+ } else {
+ mView.setVisibility(mFinalVisibility);
+ }
+ }
+ }
+ }
}
diff --git a/core/java/android/view/DisplayListCanvas.java b/core/java/android/view/DisplayListCanvas.java
index 48167c8..bb761f0 100644
--- a/core/java/android/view/DisplayListCanvas.java
+++ b/core/java/android/view/DisplayListCanvas.java
@@ -93,12 +93,6 @@ public class DisplayListCanvas extends Canvas {
private static native long nCreateDisplayListCanvas();
- public static void setProperty(String name, String value) {
- nSetProperty(name, value);
- }
-
- private static native void nSetProperty(String name, String value);
-
///////////////////////////////////////////////////////////////////////////
// Canvas management
///////////////////////////////////////////////////////////////////////////
diff --git a/core/java/android/view/LayoutInflater.java b/core/java/android/view/LayoutInflater.java
index 1503728..37312d0 100644
--- a/core/java/android/view/LayoutInflater.java
+++ b/core/java/android/view/LayoutInflater.java
@@ -590,6 +590,7 @@ public abstract class LayoutInflater {
}
}
constructor = clazz.getConstructor(mConstructorSignature);
+ constructor.setAccessible(true);
sConstructorMap.put(name, constructor);
} else {
// If we have a filter, apply it to cached constructor
@@ -615,7 +616,6 @@ public abstract class LayoutInflater {
Object[] args = mConstructorArgs;
args[1] = attrs;
- constructor.setAccessible(true);
final View view = constructor.newInstance(args);
if (view instanceof ViewStub) {
// Use the same context when inflating ViewStub later.
diff --git a/core/java/android/view/MenuInflater.java b/core/java/android/view/MenuInflater.java
index b49a59e..dc8cadf 100644
--- a/core/java/android/view/MenuInflater.java
+++ b/core/java/android/view/MenuInflater.java
@@ -544,6 +544,7 @@ public class MenuInflater {
try {
Class<?> clazz = mContext.getClassLoader().loadClass(className);
Constructor<?> constructor = clazz.getConstructor(constructorSignature);
+ constructor.setAccessible(true);
return (T) constructor.newInstance(arguments);
} catch (Exception e) {
Log.w(LOG_TAG, "Cannot instantiate class: " + className, e);
diff --git a/core/java/android/view/ThreadedRenderer.java b/core/java/android/view/ThreadedRenderer.java
index 91e6d68..1fd7109 100644
--- a/core/java/android/view/ThreadedRenderer.java
+++ b/core/java/android/view/ThreadedRenderer.java
@@ -17,6 +17,7 @@
package android.view;
import android.annotation.IntDef;
+import android.annotation.NonNull;
import android.content.Context;
import android.content.res.Resources;
import android.content.res.TypedArray;
@@ -412,6 +413,13 @@ public class ThreadedRenderer extends HardwareRenderer {
nTrimMemory(level);
}
+ public static void overrideProperty(@NonNull String name, @NonNull String value) {
+ if (name == null || value == null) {
+ throw new IllegalArgumentException("name and value must be non-null");
+ }
+ nOverrideProperty(name, value);
+ }
+
public static void dumpProfileData(byte[] data, FileDescriptor fd) {
nDumpProfileData(data, fd);
}
@@ -510,6 +518,7 @@ public class ThreadedRenderer extends HardwareRenderer {
private static native void nDestroyHardwareResources(long nativeProxy);
private static native void nTrimMemory(int level);
+ private static native void nOverrideProperty(String name, String value);
private static native void nFence(long nativeProxy);
private static native void nStopDrawing(long nativeProxy);
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 963b7a6..f62e6a2 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -28,6 +28,7 @@ import android.annotation.LayoutRes;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.Size;
+import android.annotation.UiThread;
import android.content.ClipData;
import android.content.Context;
import android.content.ContextWrapper;
@@ -700,6 +701,7 @@ import java.util.concurrent.atomic.AtomicInteger;
*
* @see android.view.ViewGroup
*/
+@UiThread
public class View implements Drawable.Callback, KeyEvent.Callback,
AccessibilityEventSource {
private static final boolean DBG = false;
@@ -2393,10 +2395,143 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
*/
static final int PFLAG3_NESTED_SCROLLING_ENABLED = 0x80;
+ /**
+ * Flag indicating that the bottom scroll indicator should be displayed
+ * when this view can scroll up.
+ */
+ static final int PFLAG3_SCROLL_INDICATOR_TOP = 0x0100;
+
+ /**
+ * Flag indicating that the bottom scroll indicator should be displayed
+ * when this view can scroll down.
+ */
+ static final int PFLAG3_SCROLL_INDICATOR_BOTTOM = 0x0200;
+
+ /**
+ * Flag indicating that the left scroll indicator should be displayed
+ * when this view can scroll left.
+ */
+ static final int PFLAG3_SCROLL_INDICATOR_LEFT = 0x0400;
+
+ /**
+ * Flag indicating that the right scroll indicator should be displayed
+ * when this view can scroll right.
+ */
+ static final int PFLAG3_SCROLL_INDICATOR_RIGHT = 0x0800;
+
+ /**
+ * Flag indicating that the start scroll indicator should be displayed
+ * when this view can scroll in the start direction.
+ */
+ static final int PFLAG3_SCROLL_INDICATOR_START = 0x1000;
+
+ /**
+ * Flag indicating that the end scroll indicator should be displayed
+ * when this view can scroll in the end direction.
+ */
+ static final int PFLAG3_SCROLL_INDICATOR_END = 0x2000;
+
/* End of masks for mPrivateFlags3 */
static final int DRAG_MASK = PFLAG2_DRAG_CAN_ACCEPT | PFLAG2_DRAG_HOVERED;
+ static final int SCROLL_INDICATORS_NONE = 0x0000;
+
+ /**
+ * Mask for use with setFlags indicating bits used for indicating which
+ * scroll indicators are enabled.
+ */
+ static final int SCROLL_INDICATORS_PFLAG3_MASK = PFLAG3_SCROLL_INDICATOR_TOP
+ | PFLAG3_SCROLL_INDICATOR_BOTTOM | PFLAG3_SCROLL_INDICATOR_LEFT
+ | PFLAG3_SCROLL_INDICATOR_RIGHT | PFLAG3_SCROLL_INDICATOR_START
+ | PFLAG3_SCROLL_INDICATOR_END;
+
+ /**
+ * Left-shift required to translate between public scroll indicator flags
+ * and internal PFLAGS3 flags. When used as a right-shift, translates
+ * PFLAGS3 flags to public flags.
+ */
+ static final int SCROLL_INDICATORS_TO_PFLAGS3_LSHIFT = 8;
+
+ /** @hide */
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef(flag = true,
+ value = {
+ SCROLL_INDICATOR_TOP,
+ SCROLL_INDICATOR_BOTTOM,
+ SCROLL_INDICATOR_LEFT,
+ SCROLL_INDICATOR_RIGHT,
+ SCROLL_INDICATOR_START,
+ SCROLL_INDICATOR_END,
+ })
+ public @interface ScrollIndicators {}
+
+ /**
+ * Scroll indicator direction for the top edge of the view.
+ *
+ * @see #setScrollIndicators(int)
+ * @see #setScrollIndicators(int, int)
+ * @see #getScrollIndicators()
+ */
+ public static final int SCROLL_INDICATOR_TOP =
+ PFLAG3_SCROLL_INDICATOR_TOP >> SCROLL_INDICATORS_TO_PFLAGS3_LSHIFT;
+
+ /**
+ * Scroll indicator direction for the bottom edge of the view.
+ *
+ * @see #setScrollIndicators(int)
+ * @see #setScrollIndicators(int, int)
+ * @see #getScrollIndicators()
+ */
+ public static final int SCROLL_INDICATOR_BOTTOM =
+ PFLAG3_SCROLL_INDICATOR_BOTTOM >> SCROLL_INDICATORS_TO_PFLAGS3_LSHIFT;
+
+ /**
+ * Scroll indicator direction for the left edge of the view.
+ *
+ * @see #setScrollIndicators(int)
+ * @see #setScrollIndicators(int, int)
+ * @see #getScrollIndicators()
+ */
+ public static final int SCROLL_INDICATOR_LEFT =
+ PFLAG3_SCROLL_INDICATOR_LEFT >> SCROLL_INDICATORS_TO_PFLAGS3_LSHIFT;
+
+ /**
+ * Scroll indicator direction for the right edge of the view.
+ *
+ * @see #setScrollIndicators(int)
+ * @see #setScrollIndicators(int, int)
+ * @see #getScrollIndicators()
+ */
+ public static final int SCROLL_INDICATOR_RIGHT =
+ PFLAG3_SCROLL_INDICATOR_RIGHT >> SCROLL_INDICATORS_TO_PFLAGS3_LSHIFT;
+
+ /**
+ * Scroll indicator direction for the starting edge of the view.
+ * <p>
+ * Resolved according to the view's layout direction, see
+ * {@link #getLayoutDirection()} for more information.
+ *
+ * @see #setScrollIndicators(int)
+ * @see #setScrollIndicators(int, int)
+ * @see #getScrollIndicators()
+ */
+ public static final int SCROLL_INDICATOR_START =
+ PFLAG3_SCROLL_INDICATOR_START >> SCROLL_INDICATORS_TO_PFLAGS3_LSHIFT;
+
+ /**
+ * Scroll indicator direction for the ending edge of the view.
+ * <p>
+ * Resolved according to the view's layout direction, see
+ * {@link #getLayoutDirection()} for more information.
+ *
+ * @see #setScrollIndicators(int)
+ * @see #setScrollIndicators(int, int)
+ * @see #getScrollIndicators()
+ */
+ public static final int SCROLL_INDICATOR_END =
+ PFLAG3_SCROLL_INDICATOR_END >> SCROLL_INDICATORS_TO_PFLAGS3_LSHIFT;
+
/**
* <p>Indicates that we are allowing {@link android.view.ViewAssistStructure} to traverse
* into this view.<p>
@@ -3215,6 +3350,8 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
@ViewDebug.ExportedProperty(deepExport = true, prefix = "fg_")
private ForegroundInfo mForegroundInfo;
+ private Drawable mScrollIndicatorDrawable;
+
/**
* RenderNode used for backgrounds.
* <p>
@@ -3767,6 +3904,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
int scrollbarStyle = SCROLLBARS_INSIDE_OVERLAY;
int overScrollMode = mOverScrollMode;
boolean initializeScrollbars = false;
+ boolean initializeScrollIndicators = false;
boolean startPaddingDefined = false;
boolean endPaddingDefined = false;
@@ -4133,6 +4271,14 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
}
mForegroundInfo.mInsidePadding = a.getBoolean(attr,
mForegroundInfo.mInsidePadding);
+ case R.styleable.View_scrollIndicators:
+ final int scrollIndicators =
+ a.getInt(attr, SCROLL_INDICATORS_NONE) & SCROLL_INDICATORS_PFLAG3_MASK;
+ if (scrollIndicators != 0) {
+ viewFlagValues |= scrollIndicators;
+ viewFlagMasks |= SCROLL_INDICATORS_PFLAG3_MASK;
+ initializeScrollIndicators = true;
+ }
break;
}
}
@@ -4209,6 +4355,10 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
initializeScrollbarsInternal(a);
}
+ if (initializeScrollIndicators) {
+ initializeScrollIndicatorsInternal();
+ }
+
a.recycle();
// Needs to be called after mViewFlags is set
@@ -4680,6 +4830,15 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
resolvePadding();
}
+ private void initializeScrollIndicatorsInternal() {
+ // Some day maybe we'll break this into top/left/start/etc. and let the
+ // client control it. Until then, you can have any scroll indicator you
+ // want as long as it's a 1dp foreground-colored rectangle.
+ if (mScrollIndicatorDrawable == null) {
+ mScrollIndicatorDrawable = mContext.getDrawable(R.drawable.scroll_indicator_material);
+ }
+ }
+
/**
* <p>
* Initalizes the scrollability cache if necessary.
@@ -4719,6 +4878,118 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
return mVerticalScrollbarPosition;
}
+ /**
+ * Sets the state of all scroll indicators.
+ * <p>
+ * See {@link #setScrollIndicators(int, int)} for usage information.
+ *
+ * @param indicators a bitmask of indicators that should be enabled, or
+ * {@code 0} to disable all indicators
+ * @see #setScrollIndicators(int, int)
+ * @see #getScrollIndicators()
+ * @attr ref android.R.styleable#View_scrollIndicators
+ */
+ public void setScrollIndicators(@ScrollIndicators int indicators) {
+ setScrollIndicators(indicators, SCROLL_INDICATORS_PFLAG3_MASK);
+ }
+
+ /**
+ * Sets the state of the scroll indicators specified by the mask. To change
+ * all scroll indicators at once, see {@link #setScrollIndicators(int)}.
+ * <p>
+ * When a scroll indicator is enabled, it will be displayed if the view
+ * can scroll in the direction of the indicator.
+ * <p>
+ * Multiple indicator types may be enabled or disabled by passing the
+ * logical OR of the desired types. If multiple types are specified, they
+ * will all be set to the same enabled state.
+ * <p>
+ * For example, to enable the top scroll indicatorExample: {@code setScrollIndicators
+ *
+ * @param indicators the indicator direction, or the logical OR of multiple
+ * indicator directions. One or more of:
+ * <ul>
+ * <li>{@link #SCROLL_INDICATOR_TOP}</li>
+ * <li>{@link #SCROLL_INDICATOR_BOTTOM}</li>
+ * <li>{@link #SCROLL_INDICATOR_LEFT}</li>
+ * <li>{@link #SCROLL_INDICATOR_RIGHT}</li>
+ * <li>{@link #SCROLL_INDICATOR_START}</li>
+ * <li>{@link #SCROLL_INDICATOR_END}</li>
+ * </ul>
+ * @see #setScrollIndicators(int)
+ * @see #getScrollIndicators()
+ * @attr ref android.R.styleable#View_scrollIndicators
+ */
+ public void setScrollIndicators(@ScrollIndicators int indicators, @ScrollIndicators int mask) {
+ // Shift and sanitize mask.
+ mask <<= SCROLL_INDICATORS_TO_PFLAGS3_LSHIFT;
+ mask &= SCROLL_INDICATORS_PFLAG3_MASK;
+
+ // Shift and mask indicators.
+ indicators <<= SCROLL_INDICATORS_TO_PFLAGS3_LSHIFT;
+ indicators &= mask;
+
+ // Merge with non-masked flags.
+ final int updatedFlags = indicators | (mPrivateFlags3 & ~mask);
+
+ if (mPrivateFlags3 != updatedFlags) {
+ mPrivateFlags3 = updatedFlags;
+
+ if (indicators != 0) {
+ initializeScrollIndicatorsInternal();
+ }
+ invalidate();
+ }
+ }
+
+ /**
+ * Returns a bitmask representing the enabled scroll indicators.
+ * <p>
+ * For example, if the top and left scroll indicators are enabled and all
+ * other indicators are disabled, the return value will be
+ * {@code View.SCROLL_INDICATOR_TOP | View.SCROLL_INDICATOR_LEFT}.
+ * <p>
+ * To check whether the bottom scroll indicator is enabled, use the value
+ * of {@code (getScrollIndicators() & View.SCROLL_INDICATOR_BOTTOM) != 0}.
+ *
+ * @return a bitmask representing the enabled scroll indicators
+ */
+ @ScrollIndicators
+ public int getScrollIndicators() {
+ return (mPrivateFlags3 & SCROLL_INDICATORS_PFLAG3_MASK)
+ >>> SCROLL_INDICATORS_TO_PFLAGS3_LSHIFT;
+ }
+
+ /**
+ * Returns whether the specified scroll indicator is enabled.
+ * <p>
+ * Multiple indicator types may be queried by passing the logical OR of the
+ * desired types. If multiple types are specified, the return value
+ * represents whether they are all enabled.
+ *
+ * @param direction the indicator direction, or the logical OR of multiple
+ * indicator directions. One or more of:
+ * <ul>
+ * <li>{@link #SCROLL_INDICATOR_TOP}</li>
+ * <li>{@link #SCROLL_INDICATOR_BOTTOM}</li>
+ * <li>{@link #SCROLL_INDICATOR_LEFT}</li>
+ * <li>{@link #SCROLL_INDICATOR_RIGHT}</li>
+ * <li>{@link #SCROLL_INDICATOR_START}</li>
+ * <li>{@link #SCROLL_INDICATOR_END}</li>
+ * </ul>
+ * @return {@code true} if the specified indicator(s) are enabled,
+ * {@code false} otherwise
+ * @attr ref android.R.styleable#View_scrollIndicators
+ */
+ public boolean isScrollIndicatorEnabled(int direction) {
+ // Shift and sanitize input.
+ direction <<= SCROLL_INDICATORS_TO_PFLAGS3_LSHIFT;
+ direction &= SCROLL_INDICATORS_PFLAG3_MASK;
+
+ // All of the flags must be set.
+ return (mPrivateFlags3 & direction) == direction;
+ }
+
ListenerInfo getListenerInfo() {
if (mListenerInfo != null) {
return mListenerInfo;
@@ -8595,7 +8866,11 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
public boolean performAccessibilityActionInternal(int action, Bundle arguments) {
if (isNestedScrollingEnabled()
&& (action == AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD
- || action == AccessibilityNodeInfo.ACTION_SCROLL_FORWARD)) {
+ || action == AccessibilityNodeInfo.ACTION_SCROLL_FORWARD
+ || action == R.id.accessibilityActionScrollUp
+ || action == R.id.accessibilityActionScrollLeft
+ || action == R.id.accessibilityActionScrollDown
+ || action == R.id.accessibilityActionScrollRight)) {
if (dispatchNestedPrePerformAccessibilityAction(action, arguments)) {
return true;
}
@@ -13438,6 +13713,75 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
}
}
+ void getScrollIndicatorBounds(@NonNull Rect out) {
+ out.left = mScrollX;
+ out.right = mScrollX + mRight - mLeft;
+ out.top = mScrollY;
+ out.bottom = mScrollY + mBottom - mTop;
+ }
+
+ private void onDrawScrollIndicators(Canvas c) {
+ if ((mPrivateFlags3 & SCROLL_INDICATORS_PFLAG3_MASK) == 0) {
+ // No scroll indicators enabled.
+ return;
+ }
+
+ final Drawable dr = mScrollIndicatorDrawable;
+ if (dr == null) {
+ // Scroll indicators aren't supported here.
+ return;
+ }
+
+ final int h = dr.getIntrinsicHeight();
+ final int w = dr.getIntrinsicWidth();
+ final Rect rect = mAttachInfo.mTmpInvalRect;
+ getScrollIndicatorBounds(rect);
+
+ if ((mPrivateFlags3 & PFLAG3_SCROLL_INDICATOR_TOP) != 0) {
+ final boolean canScrollUp = canScrollVertically(-1);
+ if (canScrollUp) {
+ dr.setBounds(rect.left, rect.top, rect.right, rect.top + h);
+ dr.draw(c);
+ }
+ }
+
+ if ((mPrivateFlags3 & PFLAG3_SCROLL_INDICATOR_BOTTOM) != 0) {
+ final boolean canScrollDown = canScrollVertically(1);
+ if (canScrollDown) {
+ dr.setBounds(rect.left, rect.bottom - h, rect.right, rect.bottom);
+ dr.draw(c);
+ }
+ }
+
+ final int leftRtl;
+ final int rightRtl;
+ if (getLayoutDirection() == LAYOUT_DIRECTION_RTL) {
+ leftRtl = PFLAG3_SCROLL_INDICATOR_END;
+ rightRtl = PFLAG3_SCROLL_INDICATOR_START;
+ } else {
+ leftRtl = PFLAG3_SCROLL_INDICATOR_START;
+ rightRtl = PFLAG3_SCROLL_INDICATOR_END;
+ }
+
+ final int leftMask = PFLAG3_SCROLL_INDICATOR_LEFT | leftRtl;
+ if ((mPrivateFlags3 & leftMask) != 0) {
+ final boolean canScrollLeft = canScrollHorizontally(-1);
+ if (canScrollLeft) {
+ dr.setBounds(rect.left, rect.top, rect.left + w, rect.bottom);
+ dr.draw(c);
+ }
+ }
+
+ final int rightMask = PFLAG3_SCROLL_INDICATOR_RIGHT | rightRtl;
+ if ((mPrivateFlags3 & rightMask) != 0) {
+ final boolean canScrollRight = canScrollHorizontally(1);
+ if (canScrollRight) {
+ dr.setBounds(rect.right - w, rect.top, rect.right, rect.bottom);
+ dr.draw(c);
+ }
+ }
+ }
+
/**
* <p>Request the drawing of the horizontal and the vertical scrollbar. The
* scrollbars are painted only if they have been awakened first.</p>
@@ -17266,6 +17610,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
* @param canvas canvas to draw into
*/
public void onDrawForeground(Canvas canvas) {
+ onDrawScrollIndicators(canvas);
onDrawScrollBars(canvas);
final Drawable foreground = mForegroundInfo != null ? mForegroundInfo.mDrawable : null;
diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java
index ef57dc3..babb4e9 100644
--- a/core/java/android/view/ViewGroup.java
+++ b/core/java/android/view/ViewGroup.java
@@ -18,6 +18,8 @@ package android.view;
import android.animation.LayoutTransition;
import android.annotation.IdRes;
+import android.annotation.NonNull;
+import android.annotation.UiThread;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
@@ -105,6 +107,7 @@ import static android.os.Build.VERSION_CODES.JELLY_BEAN_MR1;
* @attr ref android.R.styleable#ViewGroup_splitMotionEvents
* @attr ref android.R.styleable#ViewGroup_layoutMode
*/
+@UiThread
public abstract class ViewGroup extends View implements ViewParent, ViewManager {
private static final String TAG = "ViewGroup";
@@ -3545,6 +3548,21 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
return child.draw(canvas, this, drawingTime);
}
+ @Override
+ void getScrollIndicatorBounds(@NonNull Rect out) {
+ super.getScrollIndicatorBounds(out);
+
+ // If we have padding and we're supposed to clip children to that
+ // padding, offset the scroll indicators to match our clip bounds.
+ final boolean clipToPadding = (mGroupFlags & CLIP_TO_PADDING_MASK) == CLIP_TO_PADDING_MASK;
+ if (clipToPadding) {
+ out.left += mPaddingLeft;
+ out.right -= mPaddingRight;
+ out.top += mPaddingTop;
+ out.bottom -= mPaddingBottom;
+ }
+ }
+
/**
* Returns whether this group's children are clipped to their bounds before drawing.
* The default value is true.
diff --git a/core/java/android/view/accessibility/AccessibilityNodeInfo.java b/core/java/android/view/accessibility/AccessibilityNodeInfo.java
index bf4b7ae..c785149 100644
--- a/core/java/android/view/accessibility/AccessibilityNodeInfo.java
+++ b/core/java/android/view/accessibility/AccessibilityNodeInfo.java
@@ -3500,6 +3500,30 @@ public class AccessibilityNodeInfo implements Parcelable {
new AccessibilityAction(R.id.accessibilityActionScrollToPosition, null);
/**
+ * Action to scroll the node content up.
+ */
+ public static final AccessibilityAction ACTION_SCROLL_UP =
+ new AccessibilityAction(R.id.accessibilityActionScrollUp, null);
+
+ /**
+ * Action to scroll the node content left.
+ */
+ public static final AccessibilityAction ACTION_SCROLL_LEFT =
+ new AccessibilityAction(R.id.accessibilityActionScrollLeft, null);
+
+ /**
+ * Action to scroll the node content down.
+ */
+ public static final AccessibilityAction ACTION_SCROLL_DOWN =
+ new AccessibilityAction(R.id.accessibilityActionScrollDown, null);
+
+ /**
+ * Action to scroll the node content right.
+ */
+ public static final AccessibilityAction ACTION_SCROLL_RIGHT =
+ new AccessibilityAction(R.id.accessibilityActionScrollRight, null);
+
+ /**
* Action that stylus button presses the node.
*/
public static final AccessibilityAction ACTION_STYLUS_BUTTON_PRESS =
@@ -3531,6 +3555,10 @@ public class AccessibilityNodeInfo implements Parcelable {
sStandardActions.add(ACTION_SET_TEXT);
sStandardActions.add(ACTION_SHOW_ON_SCREEN);
sStandardActions.add(ACTION_SCROLL_TO_POSITION);
+ sStandardActions.add(ACTION_SCROLL_UP);
+ sStandardActions.add(ACTION_SCROLL_LEFT);
+ sStandardActions.add(ACTION_SCROLL_DOWN);
+ sStandardActions.add(ACTION_SCROLL_RIGHT);
sStandardActions.add(ACTION_STYLUS_BUTTON_PRESS);
}
diff --git a/core/java/android/widget/AbsListView.java b/core/java/android/widget/AbsListView.java
index 1df43d0..c57a53a 100644
--- a/core/java/android/widget/AbsListView.java
+++ b/core/java/android/widget/AbsListView.java
@@ -1506,10 +1506,12 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
if (isEnabled()) {
if (canScrollUp()) {
info.addAction(AccessibilityAction.ACTION_SCROLL_BACKWARD);
+ info.addAction(AccessibilityAction.ACTION_SCROLL_UP);
info.setScrollable(true);
}
if (canScrollDown()) {
info.addAction(AccessibilityAction.ACTION_SCROLL_FORWARD);
+ info.addAction(AccessibilityAction.ACTION_SCROLL_DOWN);
info.setScrollable(true);
}
}
@@ -1537,14 +1539,16 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
return true;
}
switch (action) {
- case AccessibilityNodeInfo.ACTION_SCROLL_FORWARD: {
+ case AccessibilityNodeInfo.ACTION_SCROLL_FORWARD:
+ case R.id.accessibilityActionScrollDown: {
if (isEnabled() && getLastVisiblePosition() < getCount() - 1) {
final int viewportHeight = getHeight() - mListPadding.top - mListPadding.bottom;
smoothScrollBy(viewportHeight, PositionScroller.SCROLL_DURATION);
return true;
}
} return false;
- case AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD: {
+ case AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD:
+ case R.id.accessibilityActionScrollUp: {
if (isEnabled() && mFirstPosition > 0) {
final int viewportHeight = getHeight() - mListPadding.top - mListPadding.bottom;
smoothScrollBy(-viewportHeight, PositionScroller.SCROLL_DURATION);
diff --git a/core/java/android/widget/CursorAdapter.java b/core/java/android/widget/CursorAdapter.java
index 30c74c0..d8ce60c 100644
--- a/core/java/android/widget/CursorAdapter.java
+++ b/core/java/android/widget/CursorAdapter.java
@@ -16,6 +16,7 @@
package android.widget;
+import android.annotation.WorkerThread;
import android.content.Context;
import android.content.res.Resources;
import android.database.ContentObserver;
@@ -425,6 +426,7 @@ public abstract class CursorAdapter extends BaseAdapter implements Filterable,
* @see #getFilterQueryProvider()
* @see #setFilterQueryProvider(android.widget.FilterQueryProvider)
*/
+ @WorkerThread
public Cursor runQueryOnBackgroundThread(CharSequence constraint) {
if (mFilterQueryProvider != null) {
return mFilterQueryProvider.runQuery(constraint);
diff --git a/core/java/android/widget/Editor.java b/core/java/android/widget/Editor.java
index 9b36b84..712fdba 100644
--- a/core/java/android/widget/Editor.java
+++ b/core/java/android/widget/Editor.java
@@ -318,6 +318,7 @@ public class Editor {
}
getPositionListener().addSubscriber(mCursorAnchorInfoNotifier, true);
+ resumeBlink();
}
void onDetachedFromWindow() {
@@ -327,9 +328,7 @@ public class Editor {
hideError();
}
- if (mBlink != null) {
- mBlink.removeCallbacks(mBlink);
- }
+ suspendBlink();
if (mInsertionPointCursorController != null) {
mInsertionPointCursorController.onDetached();
@@ -2422,7 +2421,8 @@ public class Editor {
public PinnedPopupWindow() {
createPopupWindow();
- mPopupWindow.setWindowLayoutType(WindowManager.LayoutParams.TYPE_APPLICATION_SUB_PANEL);
+ mPopupWindow.setWindowLayoutType(
+ WindowManager.LayoutParams.TYPE_APPLICATION_ABOVE_SUB_PANEL);
mPopupWindow.setWidth(ViewGroup.LayoutParams.WRAP_CONTENT);
mPopupWindow.setHeight(ViewGroup.LayoutParams.WRAP_CONTENT);
diff --git a/core/java/android/widget/HorizontalScrollView.java b/core/java/android/widget/HorizontalScrollView.java
index 324c2aa..0879c5d 100644
--- a/core/java/android/widget/HorizontalScrollView.java
+++ b/core/java/android/widget/HorizontalScrollView.java
@@ -40,6 +40,8 @@ import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityNodeInfo;
import android.view.animation.AnimationUtils;
+import com.android.internal.R;
+
import java.util.List;
/**
@@ -768,7 +770,8 @@ public class HorizontalScrollView extends FrameLayout {
return true;
}
switch (action) {
- case AccessibilityNodeInfo.ACTION_SCROLL_FORWARD: {
+ case AccessibilityNodeInfo.ACTION_SCROLL_FORWARD:
+ case R.id.accessibilityActionScrollRight: {
if (!isEnabled()) {
return false;
}
@@ -779,7 +782,8 @@ public class HorizontalScrollView extends FrameLayout {
return true;
}
} return false;
- case AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD: {
+ case AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD:
+ case R.id.accessibilityActionScrollLeft: {
if (!isEnabled()) {
return false;
}
@@ -807,10 +811,12 @@ public class HorizontalScrollView extends FrameLayout {
if (scrollRange > 0) {
info.setScrollable(true);
if (isEnabled() && mScrollX > 0) {
- info.addAction(AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD);
+ info.addAction(AccessibilityNodeInfo.AccessibilityAction.ACTION_SCROLL_BACKWARD);
+ info.addAction(AccessibilityNodeInfo.AccessibilityAction.ACTION_SCROLL_LEFT);
}
if (isEnabled() && mScrollX < scrollRange) {
- info.addAction(AccessibilityNodeInfo.ACTION_SCROLL_FORWARD);
+ info.addAction(AccessibilityNodeInfo.AccessibilityAction.ACTION_SCROLL_FORWARD);
+ info.addAction(AccessibilityNodeInfo.AccessibilityAction.ACTION_SCROLL_RIGHT);
}
}
}
diff --git a/core/java/android/widget/ListPopupWindow.java b/core/java/android/widget/ListPopupWindow.java
index 310412f..05866f0 100644
--- a/core/java/android/widget/ListPopupWindow.java
+++ b/core/java/android/widget/ListPopupWindow.java
@@ -39,6 +39,7 @@ import android.view.View.OnTouchListener;
import android.view.ViewConfiguration;
import android.view.ViewGroup;
import android.view.ViewParent;
+import android.view.WindowManager;
import android.view.animation.AccelerateDecelerateInterpolator;
import com.android.internal.R;
@@ -77,6 +78,7 @@ public class ListPopupWindow {
private int mDropDownWidth = ViewGroup.LayoutParams.WRAP_CONTENT;
private int mDropDownHorizontalOffset;
private int mDropDownVerticalOffset;
+ private int mDropDownWindowLayoutType = WindowManager.LayoutParams.TYPE_APPLICATION_SUB_PANEL;
private boolean mDropDownVerticalOffsetSet;
private int mDropDownGravity = Gravity.NO_GRAVITY;
@@ -515,6 +517,19 @@ public class ListPopupWindow {
}
/**
+ * Set the layout type for this popup window.
+ * <p>
+ * See {@link WindowManager.LayoutParams#type} for possible values.
+ *
+ * @param layoutType Layout type for this window.
+ *
+ * @see WindowManager.LayoutParams#type
+ */
+ public void setWindowLayoutType(int layoutType) {
+ mDropDownWindowLayoutType = layoutType;
+ }
+
+ /**
* Sets a listener to receive events when a list item is clicked.
*
* @param clickListener Listener to register
@@ -567,8 +582,9 @@ public class ListPopupWindow {
public void show() {
int height = buildDropDown();
- boolean noInputMethod = isInputMethodNotNeeded();
+ final boolean noInputMethod = isInputMethodNotNeeded();
mPopup.setAllowScrollingAnchorParent(!noInputMethod);
+ mPopup.setWindowLayoutType(mDropDownWindowLayoutType);
if (mPopup.isShowing()) {
final int widthSpec;
diff --git a/core/java/android/widget/PopupWindow.java b/core/java/android/widget/PopupWindow.java
index c3ac278..b4cbf35 100644
--- a/core/java/android/widget/PopupWindow.java
+++ b/core/java/android/widget/PopupWindow.java
@@ -829,9 +829,9 @@ public class PopupWindow {
}
/**
- * Set the layout type for this window. This value will be passed through to
- * {@link WindowManager.LayoutParams#type} therefore the value should match any value
- * {@link WindowManager.LayoutParams#type} accepts.
+ * Set the layout type for this window.
+ * <p>
+ * See {@link WindowManager.LayoutParams#type} for possible values.
*
* @param layoutType Layout type for this window.
*
diff --git a/core/java/android/widget/RemoteViewsAdapter.java b/core/java/android/widget/RemoteViewsAdapter.java
index 10e4db3..5953a98 100644
--- a/core/java/android/widget/RemoteViewsAdapter.java
+++ b/core/java/android/widget/RemoteViewsAdapter.java
@@ -618,7 +618,15 @@ public class RemoteViewsAdapter extends BaseAdapter implements Handler.Callback
// remove based on both its position as well as it's current memory usage, as well
// as whether it was directly requested vs. whether it was preloaded by our caching
// mechanism.
- mIndexRemoteViews.remove(getFarthestPositionFrom(pruneFromPosition, visibleWindow));
+ int trimIndex = getFarthestPositionFrom(pruneFromPosition, visibleWindow);
+
+ // Need to check that this is a valid index, to cover the case where you have only
+ // a single view in the cache, but it's larger than the max memory limit
+ if (trimIndex < 0) {
+ break;
+ }
+
+ mIndexRemoteViews.remove(trimIndex);
}
// Update the metadata cache
diff --git a/core/java/android/widget/ScrollView.java b/core/java/android/widget/ScrollView.java
index 2026169..98d61d3 100644
--- a/core/java/android/widget/ScrollView.java
+++ b/core/java/android/widget/ScrollView.java
@@ -819,7 +819,8 @@ public class ScrollView extends FrameLayout {
return false;
}
switch (action) {
- case AccessibilityNodeInfo.ACTION_SCROLL_FORWARD: {
+ case AccessibilityNodeInfo.ACTION_SCROLL_FORWARD:
+ case R.id.accessibilityActionScrollDown: {
final int viewportHeight = getHeight() - mPaddingBottom - mPaddingTop;
final int targetScrollY = Math.min(mScrollY + viewportHeight, getScrollRange());
if (targetScrollY != mScrollY) {
@@ -827,7 +828,8 @@ public class ScrollView extends FrameLayout {
return true;
}
} return false;
- case AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD: {
+ case AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD:
+ case R.id.accessibilityActionScrollUp: {
final int viewportHeight = getHeight() - mPaddingBottom - mPaddingTop;
final int targetScrollY = Math.max(mScrollY - viewportHeight, 0);
if (targetScrollY != mScrollY) {
@@ -853,10 +855,13 @@ public class ScrollView extends FrameLayout {
if (scrollRange > 0) {
info.setScrollable(true);
if (mScrollY > 0) {
- info.addAction(AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD);
+ info.addAction(
+ AccessibilityNodeInfo.AccessibilityAction.ACTION_SCROLL_BACKWARD);
+ info.addAction(AccessibilityNodeInfo.AccessibilityAction.ACTION_SCROLL_UP);
}
if (mScrollY < scrollRange) {
- info.addAction(AccessibilityNodeInfo.ACTION_SCROLL_FORWARD);
+ info.addAction(AccessibilityNodeInfo.AccessibilityAction.ACTION_SCROLL_FORWARD);
+ info.addAction(AccessibilityNodeInfo.AccessibilityAction.ACTION_SCROLL_DOWN);
}
}
}
diff --git a/core/java/com/android/internal/app/AlertController.java b/core/java/com/android/internal/app/AlertController.java
index b8110e3..61ee00c 100644
--- a/core/java/com/android/internal/app/AlertController.java
+++ b/core/java/com/android/internal/app/AlertController.java
@@ -526,11 +526,15 @@ public class AlertController {
mWindow.setCloseOnTouchOutsideIfNotSet(true);
}
- // Only display the divider if we have a title and a custom view or a
- // message.
if (hasTopPanel) {
+ // Only clip scrolling content to padding if we have a title.
+ if (mScrollView != null) {
+ mScrollView.setClipToPadding(true);
+ }
+
+ // Only show the divider if we have a title.
final View divider;
- if (mMessage != null || hasCustomPanel || mListView != null) {
+ if (mMessage != null || mListView != null || hasCustomPanel) {
divider = topPanel.findViewById(R.id.titleDivider);
} else {
divider = topPanel.findViewById(R.id.titleDividerTop);
@@ -541,6 +545,17 @@ public class AlertController {
}
}
+ // Update scroll indicators as needed.
+ if (!hasCustomPanel) {
+ final View content = mListView != null ? mListView : mScrollView;
+ if (content != null) {
+ final int indicators = (hasTopPanel ? View.SCROLL_INDICATOR_TOP : 0)
+ | (hasButtonPanel ? View.SCROLL_INDICATOR_BOTTOM : 0);
+ content.setScrollIndicators(indicators,
+ View.SCROLL_INDICATOR_TOP | View.SCROLL_INDICATOR_BOTTOM);
+ }
+ }
+
final TypedArray a = mContext.obtainStyledAttributes(
null, R.styleable.AlertDialog, R.attr.alertDialogStyle, 0);
setBackground(a, topPanel, contentPanel, customPanel, buttonPanel,
@@ -654,59 +669,6 @@ public class AlertController {
contentPanel.setVisibility(View.GONE);
}
}
-
- // Set up scroll indicators (if present).
- final View indicatorUp = contentPanel.findViewById(R.id.scrollIndicatorUp);
- final View indicatorDown = contentPanel.findViewById(R.id.scrollIndicatorDown);
- if (indicatorUp != null || indicatorDown != null) {
- if (mMessage != null) {
- // We're just showing the ScrollView, set up listener.
- mScrollView.setOnScrollChangeListener(new View.OnScrollChangeListener() {
- @Override
- public void onScrollChange(View v, int scrollX, int scrollY,
- int oldScrollX, int oldScrollY) {
- manageScrollIndicators(v, indicatorUp, indicatorDown);
- }
- });
- // Set up the indicators following layout.
- mScrollView.post(new Runnable() {
- @Override
- public void run() {
- manageScrollIndicators(mScrollView, indicatorUp, indicatorDown);
- }
- });
-
- } else if (mListView != null) {
- // We're just showing the AbsListView, set up listener.
- mListView.setOnScrollListener(new AbsListView.OnScrollListener() {
- @Override
- public void onScrollStateChanged(AbsListView view, int scrollState) {
- // That's cool, I guess?
- }
-
- @Override
- public void onScroll(AbsListView v, int firstVisibleItem,
- int visibleItemCount, int totalItemCount) {
- manageScrollIndicators(v, indicatorUp, indicatorDown);
- }
- });
- // Set up the indicators following layout.
- mListView.post(new Runnable() {
- @Override
- public void run() {
- manageScrollIndicators(mListView, indicatorUp, indicatorDown);
- }
- });
- } else {
- // We don't have any content to scroll, remove the indicators.
- if (indicatorUp != null) {
- contentPanel.removeView(indicatorUp);
- }
- if (indicatorDown != null) {
- contentPanel.removeView(indicatorDown);
- }
- }
- }
}
private static void manageScrollIndicators(View v, View upIndicator, View downIndicator) {
diff --git a/core/java/com/android/internal/app/IVoiceInteractionManagerService.aidl b/core/java/com/android/internal/app/IVoiceInteractionManagerService.aidl
index 4c6db24..644adb6 100644
--- a/core/java/com/android/internal/app/IVoiceInteractionManagerService.aidl
+++ b/core/java/com/android/internal/app/IVoiceInteractionManagerService.aidl
@@ -97,6 +97,12 @@ interface IVoiceInteractionManagerService {
void showSessionForActiveService(IVoiceInteractionSessionShowCallback showCallback);
/**
+ * Notifies the active service that a launch was requested from the Keyguard. This will only
+ * be called if {@link #activeServiceSupportsLaunchFromKeyguard()} returns true.
+ */
+ void launchVoiceAssistFromKeyguard();
+
+ /**
* Indicates whether there is a voice session running (but not necessarily showing).
*/
boolean isSessionRunning();
@@ -106,4 +112,10 @@ interface IVoiceInteractionManagerService {
* assist gesture.
*/
boolean activeServiceSupportsAssist();
+
+ /**
+ * Indicates whether the currently active voice interaction service is capable of being launched
+ * from the lockscreen.
+ */
+ boolean activeServiceSupportsLaunchFromKeyguard();
}
diff --git a/core/java/com/android/internal/os/BinderInternal.java b/core/java/com/android/internal/os/BinderInternal.java
index 240d9df..d77b998 100644
--- a/core/java/com/android/internal/os/BinderInternal.java
+++ b/core/java/com/android/internal/os/BinderInternal.java
@@ -20,6 +20,8 @@ import android.os.IBinder;
import android.os.SystemClock;
import android.util.EventLog;
+import dalvik.system.VMRuntime;
+
import java.lang.ref.WeakReference;
import java.util.ArrayList;
@@ -96,7 +98,7 @@ public class BinderInternal {
public static void forceGc(String reason) {
EventLog.writeEvent(2741, reason);
- Runtime.getRuntime().gc();
+ VMRuntime.getRuntime().requestConcurrentGC();
}
static void forceBinderGc() {
diff --git a/core/java/com/android/internal/os/MobileRadioPowerCalculator.java b/core/java/com/android/internal/os/MobileRadioPowerCalculator.java
index 9711c3b..8586d76 100644
--- a/core/java/com/android/internal/os/MobileRadioPowerCalculator.java
+++ b/core/java/com/android/internal/os/MobileRadioPowerCalculator.java
@@ -52,7 +52,7 @@ public class MobileRadioPowerCalculator extends PowerCalculator {
public MobileRadioPowerCalculator(PowerProfile profile, BatteryStats stats) {
mPowerRadioOn = profile.getAveragePower(PowerProfile.POWER_RADIO_ACTIVE);
for (int i = 0; i < mPowerBins.length; i++) {
- mPowerBins[i] = profile.getAveragePower(PowerProfile.POWER_RADIO_ACTIVE, i);
+ mPowerBins[i] = profile.getAveragePower(PowerProfile.POWER_RADIO_ON, i);
}
mPowerScan = profile.getAveragePower(PowerProfile.POWER_RADIO_SCANNING);
mStats = stats;
@@ -128,7 +128,9 @@ public class MobileRadioPowerCalculator extends PowerCalculator {
}
if (power != 0) {
- app.noCoveragePercent = noCoverageTimeMs * 100.0 / signalTimeMs;
+ if (signalTimeMs != 0) {
+ app.noCoveragePercent = noCoverageTimeMs * 100.0 / signalTimeMs;
+ }
app.mobileActive = remainingActiveTimeMs;
app.mobileActiveCount = stats.getMobileRadioActiveUnknownCount(statsType);
app.mobileRadioPowerMah = power;
diff --git a/core/java/com/android/internal/widget/ButtonBarLayout.java b/core/java/com/android/internal/widget/ButtonBarLayout.java
index 64e6c69..f58ab03 100644
--- a/core/java/com/android/internal/widget/ButtonBarLayout.java
+++ b/core/java/com/android/internal/widget/ButtonBarLayout.java
@@ -17,6 +17,7 @@
package com.android.internal.widget;
import android.content.Context;
+import android.content.res.TypedArray;
import android.util.AttributeSet;
import android.view.Gravity;
import android.view.View;
@@ -29,37 +30,39 @@ import com.android.internal.R;
* orientation when it can't fit its child views horizontally.
*/
public class ButtonBarLayout extends LinearLayout {
- /** Spacer used in horizontal orientation. */
- private final View mSpacer;
-
/** Whether the current configuration allows stacking. */
- private final boolean mAllowStacked;
+ private final boolean mAllowStacking;
/** Whether the layout is currently stacked. */
private boolean mStacked;
+ private int mLastWidthSize = -1;
+
public ButtonBarLayout(Context context, AttributeSet attrs) {
super(context, attrs);
- mAllowStacked = context.getResources().getBoolean(R.bool.allow_stacked_button_bar);
- mSpacer = findViewById(R.id.spacer);
+ final TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.ButtonBarLayout);
+ mAllowStacking = ta.getBoolean(R.styleable.ButtonBarLayout_allowStacking, false);
+ ta.recycle();
+
+ mStacked = getOrientation() == VERTICAL;
}
@Override
- protected void onSizeChanged(int w, int h, int oldw, int oldh) {
- super.onSizeChanged(w, h, oldw, oldh);
+ protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+ if (mAllowStacking) {
+ final int widthSize = MeasureSpec.getSize(widthMeasureSpec);
+ if (widthSize > mLastWidthSize && mStacked) {
+ // We're being measured wider this time, try un-stacking.
+ setStacked(false);
+ }
- // Maybe we can fit the content now?
- if (w > oldw && mStacked) {
- setStacked(false);
+ mLastWidthSize = widthSize;
}
- }
- @Override
- protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
- if (mAllowStacked && getOrientation() == LinearLayout.HORIZONTAL) {
+ if (mAllowStacking && !mStacked) {
final int measuredWidth = getMeasuredWidthAndState();
final int measuredWidthState = measuredWidth & MEASURED_STATE_MASK;
if (measuredWidthState == MEASURED_STATE_TOO_SMALL) {
@@ -75,8 +78,9 @@ public class ButtonBarLayout extends LinearLayout {
setOrientation(stacked ? LinearLayout.VERTICAL : LinearLayout.HORIZONTAL);
setGravity(stacked ? Gravity.RIGHT : Gravity.BOTTOM);
- if (mSpacer != null) {
- mSpacer.setVisibility(stacked ? View.GONE : View.INVISIBLE);
+ final View spacer = findViewById(R.id.spacer);
+ if (spacer != null) {
+ spacer.setVisibility(stacked ? View.GONE : View.INVISIBLE);
}
// Reverse the child order. This is specific to the Material button
diff --git a/core/java/com/android/internal/widget/ViewPager.java b/core/java/com/android/internal/widget/ViewPager.java
index 441e640..e76302b 100644
--- a/core/java/com/android/internal/widget/ViewPager.java
+++ b/core/java/com/android/internal/widget/ViewPager.java
@@ -47,6 +47,8 @@ import android.view.animation.Interpolator;
import android.widget.EdgeEffect;
import android.widget.Scroller;
+import com.android.internal.R;
+
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
@@ -2720,10 +2722,12 @@ public class ViewPager extends ViewGroup {
if (canScrollHorizontally(1)) {
info.addAction(AccessibilityAction.ACTION_SCROLL_FORWARD);
+ info.addAction(AccessibilityAction.ACTION_SCROLL_RIGHT);
}
if (canScrollHorizontally(-1)) {
info.addAction(AccessibilityAction.ACTION_SCROLL_BACKWARD);
+ info.addAction(AccessibilityAction.ACTION_SCROLL_LEFT);
}
}
@@ -2735,12 +2739,14 @@ public class ViewPager extends ViewGroup {
switch (action) {
case AccessibilityNodeInfo.ACTION_SCROLL_FORWARD:
+ case R.id.accessibilityActionScrollRight:
if (canScrollHorizontally(1)) {
setCurrentItem(mCurItem + 1);
return true;
}
return false;
case AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD:
+ case R.id.accessibilityActionScrollLeft:
if (canScrollHorizontally(-1)) {
setCurrentItem(mCurItem - 1);
return true;