summaryrefslogtreecommitdiffstats
path: root/core/java/android
diff options
context:
space:
mode:
Diffstat (limited to 'core/java/android')
-rw-r--r--core/java/android/accounts/AccountManager.java66
-rw-r--r--core/java/android/accounts/ChooseTypeAndAccountActivity.java16
-rw-r--r--core/java/android/app/ActionBar.java5
-rw-r--r--core/java/android/app/Activity.java4
-rw-r--r--core/java/android/app/ActivityManagerNative.java8
-rw-r--r--core/java/android/app/ActivityTransitionCoordinator.java13
-rw-r--r--core/java/android/app/AppOpsManager.java30
-rw-r--r--core/java/android/app/ContextImpl.java81
-rw-r--r--core/java/android/app/EnterTransitionCoordinator.java1
-rw-r--r--core/java/android/app/ExitTransitionCoordinator.java2
-rw-r--r--core/java/android/app/IActivityManager.java2
-rw-r--r--core/java/android/app/assist/AssistStructure.java2
-rw-r--r--core/java/android/bluetooth/BluetoothDevice.java3
-rw-r--r--core/java/android/bluetooth/BluetoothSocket.java2
-rw-r--r--core/java/android/content/Context.java38
-rw-r--r--core/java/android/content/ContextWrapper.java18
-rw-r--r--core/java/android/content/Intent.java7
-rw-r--r--core/java/android/content/pm/IPackageManager.aidl3
-rw-r--r--core/java/android/content/pm/IntentFilterVerificationInfo.java28
-rw-r--r--core/java/android/content/pm/PackageUserState.java2
-rw-r--r--core/java/android/content/res/ColorStateList.java2
-rw-r--r--core/java/android/content/res/Resources.java1
-rw-r--r--core/java/android/hardware/SystemSensorManager.java32
-rw-r--r--core/java/android/hardware/camera2/CameraCharacteristics.java20
-rw-r--r--core/java/android/hardware/camera2/CameraManager.java55
-rw-r--r--core/java/android/hardware/camera2/CameraMetadata.java10
-rw-r--r--core/java/android/hardware/usb/IUsbManager.aidl11
-rw-r--r--core/java/android/hardware/usb/UsbManager.java106
-rw-r--r--core/java/android/hardware/usb/UsbPort.aidl19
-rw-r--r--core/java/android/hardware/usb/UsbPort.java238
-rw-r--r--core/java/android/hardware/usb/UsbPortStatus.aidl19
-rw-r--r--core/java/android/hardware/usb/UsbPortStatus.java144
-rw-r--r--core/java/android/inputmethodservice/ExtractEditText.java29
-rw-r--r--core/java/android/net/IConnectivityManager.aidl2
-rw-r--r--core/java/android/os/BatteryStats.java16
-rw-r--r--core/java/android/os/IDeviceIdleController.aidl3
-rw-r--r--core/java/android/os/IPowerManager.aidl2
-rw-r--r--core/java/android/os/PowerManager.java12
-rw-r--r--core/java/android/os/storage/IMountService.java41
-rw-r--r--core/java/android/os/storage/MountServiceInternal.java82
-rw-r--r--core/java/android/os/storage/StorageManager.java45
-rw-r--r--core/java/android/os/storage/VolumeInfo.java6
-rw-r--r--core/java/android/provider/Settings.java17
-rw-r--r--core/java/android/service/dreams/Sandman.java3
-rw-r--r--core/java/android/service/voice/VoiceInteractionService.java31
-rw-r--r--core/java/android/service/voice/VoiceInteractionSession.java35
-rw-r--r--core/java/android/text/Html.java7
-rw-r--r--core/java/android/text/SpannableStringInternal.java9
-rw-r--r--core/java/android/util/LocalLog.java6
-rw-r--r--core/java/android/widget/AppSecurityPermissions.java39
-rw-r--r--core/java/android/widget/Editor.java66
-rw-r--r--core/java/android/widget/Switch.java2
-rw-r--r--core/java/android/widget/TextView.java29
53 files changed, 1218 insertions, 252 deletions
diff --git a/core/java/android/accounts/AccountManager.java b/core/java/android/accounts/AccountManager.java
index aa7692b..dd3d3a8 100644
--- a/core/java/android/accounts/AccountManager.java
+++ b/core/java/android/accounts/AccountManager.java
@@ -43,6 +43,7 @@ import com.google.android.collect.Maps;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
+import java.util.List;
import java.util.Map;
import java.util.concurrent.Callable;
import java.util.concurrent.CancellationException;
@@ -2259,6 +2260,9 @@ public class AccountManager {
}
/**
+ * Deprecated in favor of {@link #newChooseAccountIntent(Account, List, String[], String,
+ * String, String[], Bundle)}.
+ *
* Returns an intent to an {@link Activity} that prompts the user to choose from a list of
* accounts.
* The caller will then typically start the activity by calling
@@ -2273,14 +2277,13 @@ public class AccountManager {
* null, null, null);</pre>
* @param selectedAccount if specified, indicates that the {@link Account} is the currently
* selected one, according to the caller's definition of selected.
- * @param allowableAccounts an optional {@link ArrayList} of accounts that are allowed to be
+ * @param allowableAccounts an optional {@link List} of accounts that are allowed to be
* shown. If not specified then this field will not limit the displayed accounts.
* @param allowableAccountTypes an optional string array of account types. These are used
* both to filter the shown accounts and to filter the list of account types that are shown
* when adding an account. If not specified then this field will not limit the displayed
* account types when adding an account.
- * @param alwaysPromptForAccount if set the account chooser screen is always shown, otherwise
- * it is only shown when there is more than one account from which to choose
+ * @param alwaysPromptForAccount boolean that is ignored.
* @param descriptionOverrideText if non-null this string is used as the description in the
* accounts chooser screen rather than the default
* @param addAccountAuthTokenType this string is passed as the {@link #addAccount}
@@ -2291,7 +2294,9 @@ public class AccountManager {
* parameter
* @return an {@link Intent} that can be used to launch the ChooseAccount activity flow.
*/
- static public Intent newChooseAccountIntent(Account selectedAccount,
+ @Deprecated
+ static public Intent newChooseAccountIntent(
+ Account selectedAccount,
ArrayList<Account> allowableAccounts,
String[] allowableAccountTypes,
boolean alwaysPromptForAccount,
@@ -2299,20 +2304,67 @@ public class AccountManager {
String addAccountAuthTokenType,
String[] addAccountRequiredFeatures,
Bundle addAccountOptions) {
+ return newChooseAccountIntent(
+ selectedAccount,
+ allowableAccounts,
+ allowableAccountTypes,
+ descriptionOverrideText,
+ addAccountAuthTokenType,
+ addAccountRequiredFeatures,
+ addAccountOptions);
+ }
+
+ /**
+ * Returns an intent to an {@link Activity} that prompts the user to choose from a list of
+ * accounts.
+ * The caller will then typically start the activity by calling
+ * <code>startActivityForResult(intent, ...);</code>.
+ * <p>
+ * On success the activity returns a Bundle with the account name and type specified using
+ * keys {@link #KEY_ACCOUNT_NAME} and {@link #KEY_ACCOUNT_TYPE}.
+ * <p>
+ * The most common case is to call this with one account type, e.g.:
+ * <p>
+ * <pre> newChooseAccountIntent(null, null, new String[]{"com.google"}, null, null, null,
+ * null);</pre>
+ * @param selectedAccount if specified, indicates that the {@link Account} is the currently
+ * selected one, according to the caller's definition of selected.
+ * @param allowableAccounts an optional {@link List} of accounts that are allowed to be
+ * shown. If not specified then this field will not limit the displayed accounts.
+ * @param allowableAccountTypes an optional string array of account types. These are used
+ * both to filter the shown accounts and to filter the list of account types that are shown
+ * when adding an account. If not specified then this field will not limit the displayed
+ * account types when adding an account.
+ * @param descriptionOverrideText if non-null this string is used as the description in the
+ * accounts chooser screen rather than the default
+ * @param addAccountAuthTokenType this string is passed as the {@link #addAccount}
+ * authTokenType parameter
+ * @param addAccountRequiredFeatures this string array is passed as the {@link #addAccount}
+ * requiredFeatures parameter
+ * @param addAccountOptions This {@link Bundle} is passed as the {@link #addAccount} options
+ * parameter
+ * @return an {@link Intent} that can be used to launch the ChooseAccount activity flow.
+ */
+ static public Intent newChooseAccountIntent(
+ Account selectedAccount,
+ List<Account> allowableAccounts,
+ String[] allowableAccountTypes,
+ String descriptionOverrideText,
+ String addAccountAuthTokenType,
+ String[] addAccountRequiredFeatures,
+ Bundle addAccountOptions) {
Intent intent = new Intent();
ComponentName componentName = ComponentName.unflattenFromString(
Resources.getSystem().getString(R.string.config_chooseTypeAndAccountActivity));
intent.setClassName(componentName.getPackageName(),
componentName.getClassName());
intent.putExtra(ChooseTypeAndAccountActivity.EXTRA_ALLOWABLE_ACCOUNTS_ARRAYLIST,
- allowableAccounts);
+ allowableAccounts == null ? null : new ArrayList<Account>(allowableAccounts));
intent.putExtra(ChooseTypeAndAccountActivity.EXTRA_ALLOWABLE_ACCOUNT_TYPES_STRING_ARRAY,
allowableAccountTypes);
intent.putExtra(ChooseTypeAndAccountActivity.EXTRA_ADD_ACCOUNT_OPTIONS_BUNDLE,
addAccountOptions);
intent.putExtra(ChooseTypeAndAccountActivity.EXTRA_SELECTED_ACCOUNT, selectedAccount);
- intent.putExtra(ChooseTypeAndAccountActivity.EXTRA_ALWAYS_PROMPT_FOR_ACCOUNT,
- alwaysPromptForAccount);
intent.putExtra(ChooseTypeAndAccountActivity.EXTRA_DESCRIPTION_TEXT_OVERRIDE,
descriptionOverrideText);
intent.putExtra(ChooseTypeAndAccountActivity.EXTRA_ADD_ACCOUNT_AUTH_TOKEN_TYPE_STRING,
diff --git a/core/java/android/accounts/ChooseTypeAndAccountActivity.java b/core/java/android/accounts/ChooseTypeAndAccountActivity.java
index c06b462..133df2b 100644
--- a/core/java/android/accounts/ChooseTypeAndAccountActivity.java
+++ b/core/java/android/accounts/ChooseTypeAndAccountActivity.java
@@ -88,9 +88,10 @@ public class ChooseTypeAndAccountActivity extends Activity
public static final String EXTRA_SELECTED_ACCOUNT = "selectedAccount";
/**
- * If true then display the account selection list even if there is just
- * one account to choose from. boolean.
+ * Deprecated. Providing this extra to {@link ChooseTypeAndAccountActivity}
+ * will have no effect.
*/
+ @Deprecated
public static final String EXTRA_ALWAYS_PROMPT_FOR_ACCOUNT =
"alwaysPromptForAccount";
@@ -117,7 +118,6 @@ public class ChooseTypeAndAccountActivity extends Activity
private Set<String> mSetOfRelevantAccountTypes;
private String mSelectedAccountName = null;
private boolean mSelectedAddNewAccount = false;
- private boolean mAlwaysPromptForAccount = false;
private String mDescriptionOverride;
private ArrayList<Account> mAccounts;
@@ -188,7 +188,6 @@ public class ChooseTypeAndAccountActivity extends Activity
mSetOfAllowableAccounts = getAllowableAccountSet(intent);
mSetOfRelevantAccountTypes = getReleventAccountTypes(intent);
- mAlwaysPromptForAccount = intent.getBooleanExtra(EXTRA_ALWAYS_PROMPT_FOR_ACCOUNT, false);
mDescriptionOverride = intent.getStringExtra(EXTRA_DESCRIPTION_TEXT_OVERRIDE);
mAccounts = getAcceptableAccountChoices(AccountManager.get(this));
@@ -218,15 +217,6 @@ public class ChooseTypeAndAccountActivity extends Activity
} else {
startChooseAccountTypeActivity();
}
- return;
- }
-
- // if there is only one allowable account return it
- if (!mAlwaysPromptForAccount && mAccounts.size() == 1) {
- Account account = mAccounts.get(0);
- super.onCreate(savedInstanceState);
- setResultAndFinish(account.name, account.type);
- return;
}
}
diff --git a/core/java/android/app/ActionBar.java b/core/java/android/app/ActionBar.java
index 4d34349..72f8c77 100644
--- a/core/java/android/app/ActionBar.java
+++ b/core/java/android/app/ActionBar.java
@@ -1057,6 +1057,11 @@ public abstract class ActionBar {
}
/** @hide */
+ public boolean onKeyShortcut(int keyCode, KeyEvent event) {
+ return false;
+ }
+
+ /** @hide */
public boolean collapseActionView() {
return false;
}
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index d07238a..7572799 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -2469,7 +2469,9 @@ public class Activity extends ContextThemeWrapper
* @return True if the key shortcut was handled.
*/
public boolean onKeyShortcut(int keyCode, KeyEvent event) {
- return false;
+ // Let the Action Bar have a chance at handling the shortcut.
+ ActionBar actionBar = getActionBar();
+ return (actionBar != null && actionBar.onKeyShortcut(keyCode, event));
}
/**
diff --git a/core/java/android/app/ActivityManagerNative.java b/core/java/android/app/ActivityManagerNative.java
index cc93ac9..fc408a8 100644
--- a/core/java/android/app/ActivityManagerNative.java
+++ b/core/java/android/app/ActivityManagerNative.java
@@ -456,14 +456,14 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM
int resultCode = data.readInt();
String resultData = data.readString();
Bundle resultExtras = data.readBundle();
- String perm = data.readString();
+ String[] perms = data.readStringArray();
int appOp = data.readInt();
Bundle options = data.readBundle();
boolean serialized = data.readInt() != 0;
boolean sticky = data.readInt() != 0;
int userId = data.readInt();
int res = broadcastIntent(app, intent, resolvedType, resultTo,
- resultCode, resultData, resultExtras, perm, appOp,
+ resultCode, resultData, resultExtras, perms, appOp,
options, serialized, sticky, userId);
reply.writeNoException();
reply.writeInt(res);
@@ -3007,7 +3007,7 @@ class ActivityManagerProxy implements IActivityManager
public int broadcastIntent(IApplicationThread caller,
Intent intent, String resolvedType, IIntentReceiver resultTo,
int resultCode, String resultData, Bundle map,
- String requiredPermission, int appOp, Bundle options, boolean serialized,
+ String[] requiredPermissions, int appOp, Bundle options, boolean serialized,
boolean sticky, int userId) throws RemoteException
{
Parcel data = Parcel.obtain();
@@ -3020,7 +3020,7 @@ class ActivityManagerProxy implements IActivityManager
data.writeInt(resultCode);
data.writeString(resultData);
data.writeBundle(map);
- data.writeString(requiredPermission);
+ data.writeStringArray(requiredPermissions);
data.writeInt(appOp);
data.writeBundle(options);
data.writeInt(serialized ? 1 : 0);
diff --git a/core/java/android/app/ActivityTransitionCoordinator.java b/core/java/android/app/ActivityTransitionCoordinator.java
index fa81412..e28fb20 100644
--- a/core/java/android/app/ActivityTransitionCoordinator.java
+++ b/core/java/android/app/ActivityTransitionCoordinator.java
@@ -217,11 +217,6 @@ abstract class ActivityTransitionCoordinator extends ResultReceiver {
}
protected void viewsReady(ArrayMap<String, View> sharedElements) {
- final View decor = getDecor();
- final ViewRootImpl viewRoot = decor == null ? null : decor.getViewRootImpl();
- if (viewRoot != null) {
- viewRoot.setPausedForTransition(true);
- }
sharedElements.retainAll(mAllSharedElementNames);
if (mListener != null) {
mListener.onMapSharedElements(mAllSharedElementNames, sharedElements);
@@ -905,6 +900,14 @@ abstract class ActivityTransitionCoordinator extends ResultReceiver {
}
}
+ protected void pauseInput() {
+ final View decor = getDecor();
+ final ViewRootImpl viewRoot = decor == null ? null : decor.getViewRootImpl();
+ if (viewRoot != null) {
+ viewRoot.setPausedForTransition(true);
+ }
+ }
+
protected void onTransitionsComplete() {}
protected class ContinueTransitionListener extends Transition.TransitionListenerAdapter {
diff --git a/core/java/android/app/AppOpsManager.java b/core/java/android/app/AppOpsManager.java
index bf3bfae..08e1696 100644
--- a/core/java/android/app/AppOpsManager.java
+++ b/core/java/android/app/AppOpsManager.java
@@ -233,8 +233,10 @@ public class AppOpsManager {
public static final int OP_READ_EXTERNAL_STORAGE = 59;
/** @hide Write external storage. */
public static final int OP_WRITE_EXTERNAL_STORAGE = 60;
+ /** @hide Turned on the screen. */
+ public static final int OP_TURN_SCREEN_ON = 61;
/** @hide */
- public static final int _NUM_OP = 61;
+ public static final int _NUM_OP = 62;
/** Access to coarse location information. */
public static final String OPSTR_COARSE_LOCATION = "android:coarse_location";
@@ -393,7 +395,8 @@ public class AppOpsManager {
OP_READ_CELL_BROADCASTS,
OP_MOCK_LOCATION,
OP_READ_EXTERNAL_STORAGE,
- OP_WRITE_EXTERNAL_STORAGE
+ OP_WRITE_EXTERNAL_STORAGE,
+ OP_TURN_SCREEN_ON,
};
/**
@@ -461,7 +464,8 @@ public class AppOpsManager {
OPSTR_READ_CELL_BROADCASTS,
OPSTR_MOCK_LOCATION,
OPSTR_READ_EXTERNAL_STORAGE,
- OPSTR_WRITE_EXTERNAL_STORAGE
+ OPSTR_WRITE_EXTERNAL_STORAGE,
+ null,
};
/**
@@ -528,8 +532,9 @@ public class AppOpsManager {
"BODY_SENSORS",
"READ_CELL_BROADCASTS",
"MOCK_LOCATION",
- "OPSTR_READ_EXTERNAL_STORAGE",
- "OPSTR_WRITE_EXTERNAL_STORAGE",
+ "READ_EXTERNAL_STORAGE",
+ "WRITE_EXTERNAL_STORAGE",
+ "TURN_ON_SCREEN",
};
/**
@@ -598,6 +603,7 @@ public class AppOpsManager {
null,
Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.WRITE_EXTERNAL_STORAGE,
+ null, // no permission for turning the screen on
};
/**
@@ -666,7 +672,8 @@ public class AppOpsManager {
null, // READ_CELL_BROADCASTS
null, // MOCK_LOCATION
null, // READ_EXTERNAL_STORAGE
- null // WRITE_EXTERNAL_STORAGE
+ null, // WRITE_EXTERNAL_STORAGE
+ null, // TURN_ON_SCREEN
};
/**
@@ -734,7 +741,8 @@ public class AppOpsManager {
false, // READ_CELL_BROADCASTS
false, // MOCK_LOCATION
false, // READ_EXTERNAL_STORAGE
- false // WRITE_EXTERNAL_STORAGE
+ false, // WRITE_EXTERNAL_STORAGE
+ false, // TURN_ON_SCREEN
};
/**
@@ -765,7 +773,7 @@ public class AppOpsManager {
AppOpsManager.MODE_ALLOWED,
AppOpsManager.MODE_ALLOWED,
AppOpsManager.MODE_ALLOWED,
- AppOpsManager.MODE_ALLOWED,
+ AppOpsManager.MODE_DEFAULT, // OP_SYSTEM_ALERT_WINDOW
AppOpsManager.MODE_ALLOWED,
AppOpsManager.MODE_ALLOWED,
AppOpsManager.MODE_ALLOWED,
@@ -801,7 +809,8 @@ public class AppOpsManager {
AppOpsManager.MODE_ALLOWED,
AppOpsManager.MODE_ERRORED, // OP_MOCK_LOCATION
AppOpsManager.MODE_ALLOWED,
- AppOpsManager.MODE_ALLOWED
+ AppOpsManager.MODE_ALLOWED,
+ AppOpsManager.MODE_ALLOWED, // OP_TURN_ON_SCREEN
};
/**
@@ -872,7 +881,8 @@ public class AppOpsManager {
false,
false,
false,
- false
+ false,
+ false,
};
/**
diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java
index 6639486..235f294 100644
--- a/core/java/android/app/ContextImpl.java
+++ b/core/java/android/app/ContextImpl.java
@@ -180,7 +180,7 @@ class ContextImpl extends Context {
@GuardedBy("mSync")
private File[] mExternalMediaDirs;
- private static final String[] EMPTY_FILE_LIST = {};
+ private static final String[] EMPTY_STRING_ARRAY = {};
// The system service cache for the system services that are cached per-ContextImpl.
final Object[] mServiceCache = SystemServiceRegistry.createServiceCache();
@@ -552,7 +552,7 @@ class ContextImpl extends Context {
@Override
public String[] fileList() {
final String[] list = getFilesDir().list();
- return (list != null) ? list : EMPTY_FILE_LIST;
+ return (list != null) ? list : EMPTY_STRING_ARRAY;
}
@Override
@@ -591,7 +591,7 @@ class ContextImpl extends Context {
@Override
public String[] databaseList() {
final String[] list = getDatabasesDir().list();
- return (list != null) ? list : EMPTY_FILE_LIST;
+ return (list != null) ? list : EMPTY_STRING_ARRAY;
}
@@ -777,11 +777,28 @@ class ContextImpl extends Context {
public void sendBroadcast(Intent intent, String receiverPermission) {
warnIfCallingFromSystemProcess();
String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
+ String[] receiverPermissions = receiverPermission == null ? null
+ : new String[] {receiverPermission};
try {
intent.prepareToLeaveProcess();
ActivityManagerNative.getDefault().broadcastIntent(
mMainThread.getApplicationThread(), intent, resolvedType, null,
- Activity.RESULT_OK, null, null, receiverPermission, AppOpsManager.OP_NONE,
+ Activity.RESULT_OK, null, null, receiverPermissions, AppOpsManager.OP_NONE,
+ null, false, false, getUserId());
+ } catch (RemoteException e) {
+ throw new RuntimeException("Failure from system", e);
+ }
+ }
+
+ @Override
+ public void sendBroadcastMultiplePermissions(Intent intent, String[] receiverPermissions) {
+ warnIfCallingFromSystemProcess();
+ String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
+ try {
+ intent.prepareToLeaveProcess();
+ ActivityManagerNative.getDefault().broadcastIntent(
+ mMainThread.getApplicationThread(), intent, resolvedType, null,
+ Activity.RESULT_OK, null, null, receiverPermissions, AppOpsManager.OP_NONE,
null, false, false, getUserId());
} catch (RemoteException e) {
throw new RuntimeException("Failure from system", e);
@@ -792,11 +809,13 @@ class ContextImpl extends Context {
public void sendBroadcast(Intent intent, String receiverPermission, Bundle options) {
warnIfCallingFromSystemProcess();
String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
+ String[] receiverPermissions = receiverPermission == null ? null
+ : new String[] {receiverPermission};
try {
intent.prepareToLeaveProcess();
ActivityManagerNative.getDefault().broadcastIntent(
mMainThread.getApplicationThread(), intent, resolvedType, null,
- Activity.RESULT_OK, null, null, receiverPermission, AppOpsManager.OP_NONE,
+ Activity.RESULT_OK, null, null, receiverPermissions, AppOpsManager.OP_NONE,
options, false, false, getUserId());
} catch (RemoteException e) {
throw new RuntimeException("Failure from system", e);
@@ -807,11 +826,13 @@ class ContextImpl extends Context {
public void sendBroadcast(Intent intent, String receiverPermission, int appOp) {
warnIfCallingFromSystemProcess();
String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
+ String[] receiverPermissions = receiverPermission == null ? null
+ : new String[] {receiverPermission};
try {
intent.prepareToLeaveProcess();
ActivityManagerNative.getDefault().broadcastIntent(
mMainThread.getApplicationThread(), intent, resolvedType, null,
- Activity.RESULT_OK, null, null, receiverPermission, appOp, null, false, false,
+ Activity.RESULT_OK, null, null, receiverPermissions, appOp, null, false, false,
getUserId());
} catch (RemoteException e) {
throw new RuntimeException("Failure from system", e);
@@ -822,11 +843,13 @@ class ContextImpl extends Context {
public void sendOrderedBroadcast(Intent intent, String receiverPermission) {
warnIfCallingFromSystemProcess();
String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
+ String[] receiverPermissions = receiverPermission == null ? null
+ : new String[] {receiverPermission};
try {
intent.prepareToLeaveProcess();
ActivityManagerNative.getDefault().broadcastIntent(
mMainThread.getApplicationThread(), intent, resolvedType, null,
- Activity.RESULT_OK, null, null, receiverPermission, AppOpsManager.OP_NONE,
+ Activity.RESULT_OK, null, null, receiverPermissions, AppOpsManager.OP_NONE,
null, true, false, getUserId());
} catch (RemoteException e) {
throw new RuntimeException("Failure from system", e);
@@ -883,11 +906,13 @@ class ContextImpl extends Context {
}
}
String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
+ String[] receiverPermissions = receiverPermission == null ? null
+ : new String[] {receiverPermission};
try {
intent.prepareToLeaveProcess();
ActivityManagerNative.getDefault().broadcastIntent(
mMainThread.getApplicationThread(), intent, resolvedType, rd,
- initialCode, initialData, initialExtras, receiverPermission, appOp,
+ initialCode, initialData, initialExtras, receiverPermissions, appOp,
options, true, false, getUserId());
} catch (RemoteException e) {
throw new RuntimeException("Failure from system", e);
@@ -917,11 +942,13 @@ class ContextImpl extends Context {
public void sendBroadcastAsUser(Intent intent, UserHandle user,
String receiverPermission, int appOp) {
String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
+ String[] receiverPermissions = receiverPermission == null ? null
+ : new String[] {receiverPermission};
try {
intent.prepareToLeaveProcess();
ActivityManagerNative.getDefault().broadcastIntent(
mMainThread.getApplicationThread(), intent, resolvedType, null,
- Activity.RESULT_OK, null, null, receiverPermission, appOp, null, false, false,
+ Activity.RESULT_OK, null, null, receiverPermissions, appOp, null, false, false,
user.getIdentifier());
} catch (RemoteException e) {
throw new RuntimeException("Failure from system", e);
@@ -933,14 +960,21 @@ class ContextImpl extends Context {
String receiverPermission, BroadcastReceiver resultReceiver, Handler scheduler,
int initialCode, String initialData, Bundle initialExtras) {
sendOrderedBroadcastAsUser(intent, user, receiverPermission, AppOpsManager.OP_NONE,
- resultReceiver, scheduler, initialCode, initialData, initialExtras);
+ null, resultReceiver, scheduler, initialCode, initialData, initialExtras);
}
@Override
public void sendOrderedBroadcastAsUser(Intent intent, UserHandle user,
String receiverPermission, int appOp, BroadcastReceiver resultReceiver,
- Handler scheduler,
- int initialCode, String initialData, Bundle initialExtras) {
+ Handler scheduler, int initialCode, String initialData, Bundle initialExtras) {
+ sendOrderedBroadcastAsUser(intent, user, receiverPermission, appOp,
+ null, resultReceiver, scheduler, initialCode, initialData, initialExtras);
+ }
+
+ @Override
+ public void sendOrderedBroadcastAsUser(Intent intent, UserHandle user,
+ String receiverPermission, int appOp, Bundle options, BroadcastReceiver resultReceiver,
+ Handler scheduler, int initialCode, String initialData, Bundle initialExtras) {
IIntentReceiver rd = null;
if (resultReceiver != null) {
if (mPackageInfo != null) {
@@ -954,17 +988,19 @@ class ContextImpl extends Context {
if (scheduler == null) {
scheduler = mMainThread.getHandler();
}
- rd = new LoadedApk.ReceiverDispatcher(
- resultReceiver, getOuterContext(), scheduler, null, false).getIIntentReceiver();
+ rd = new LoadedApk.ReceiverDispatcher(resultReceiver, getOuterContext(),
+ scheduler, null, false).getIIntentReceiver();
}
}
String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
+ String[] receiverPermissions = receiverPermission == null ? null
+ : new String[] {receiverPermission};
try {
intent.prepareToLeaveProcess();
ActivityManagerNative.getDefault().broadcastIntent(
mMainThread.getApplicationThread(), intent, resolvedType, rd,
- initialCode, initialData, initialExtras, receiverPermission,
- appOp, null, true, false, user.getIdentifier());
+ initialCode, initialData, initialExtras, receiverPermissions,
+ appOp, options, true, false, user.getIdentifier());
} catch (RemoteException e) {
throw new RuntimeException("Failure from system", e);
}
@@ -1925,13 +1961,14 @@ class ContextImpl extends Context {
// enough permissions; ask vold to create on our behalf.
final IMountService mount = IMountService.Stub.asInterface(
ServiceManager.getService("mount"));
- int res = -1;
try {
- res = mount.mkdirs(getPackageName(), dir.getAbsolutePath());
- } catch (Exception ignored) {
- }
- if (res != 0) {
- Log.w(TAG, "Failed to ensure directory: " + dir);
+ final int res = mount.mkdirs(getPackageName(), dir.getAbsolutePath());
+ if (res != 0) {
+ Log.w(TAG, "Failed to ensure " + dir + ": " + res);
+ dir = null;
+ }
+ } catch (Exception e) {
+ Log.w(TAG, "Failed to ensure " + dir + ": " + e);
dir = null;
}
}
diff --git a/core/java/android/app/EnterTransitionCoordinator.java b/core/java/android/app/EnterTransitionCoordinator.java
index 05cf1d4..0745537 100644
--- a/core/java/android/app/EnterTransitionCoordinator.java
+++ b/core/java/android/app/EnterTransitionCoordinator.java
@@ -333,6 +333,7 @@ class EnterTransitionCoordinator extends ActivityTransitionCoordinator {
boolean startSharedElementTransition = true;
setGhostVisibility(View.INVISIBLE);
scheduleGhostVisibilityChange(View.INVISIBLE);
+ pauseInput();
Transition transition = beginTransition(decorView, startEnterTransition,
startSharedElementTransition);
scheduleGhostVisibilityChange(View.VISIBLE);
diff --git a/core/java/android/app/ExitTransitionCoordinator.java b/core/java/android/app/ExitTransitionCoordinator.java
index 9ddebb0..ad104a4 100644
--- a/core/java/android/app/ExitTransitionCoordinator.java
+++ b/core/java/android/app/ExitTransitionCoordinator.java
@@ -203,6 +203,7 @@ class ExitTransitionCoordinator extends ActivityTransitionCoordinator {
public void startExit() {
if (!mIsExitStarted) {
mIsExitStarted = true;
+ pauseInput();
ViewGroup decorView = getDecor();
if (decorView != null) {
decorView.suppressLayout(true);
@@ -220,6 +221,7 @@ class ExitTransitionCoordinator extends ActivityTransitionCoordinator {
public void startExit(int resultCode, Intent data) {
if (!mIsExitStarted) {
mIsExitStarted = true;
+ pauseInput();
ViewGroup decorView = getDecor();
if (decorView != null) {
decorView.suppressLayout(true);
diff --git a/core/java/android/app/IActivityManager.java b/core/java/android/app/IActivityManager.java
index acce81c..1d87d77 100644
--- a/core/java/android/app/IActivityManager.java
+++ b/core/java/android/app/IActivityManager.java
@@ -106,7 +106,7 @@ public interface IActivityManager extends IInterface {
public void unregisterReceiver(IIntentReceiver receiver) throws RemoteException;
public int broadcastIntent(IApplicationThread caller, Intent intent,
String resolvedType, IIntentReceiver resultTo, int resultCode,
- String resultData, Bundle map, String requiredPermission,
+ String resultData, Bundle map, String[] requiredPermissions,
int appOp, Bundle options, boolean serialized, boolean sticky, int userId) throws RemoteException;
public void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) throws RemoteException;
public void finishReceiver(IBinder who, int resultCode, String resultData, Bundle map,
diff --git a/core/java/android/app/assist/AssistStructure.java b/core/java/android/app/assist/AssistStructure.java
index 9673c98..40126d6 100644
--- a/core/java/android/app/assist/AssistStructure.java
+++ b/core/java/android/app/assist/AssistStructure.java
@@ -812,7 +812,7 @@ public class AssistStructure implements Parcelable {
* Returns true if assist data has been blocked starting at this node in the hierarchy.
*/
public boolean isAssistBlocked() {
- return (mFlags&ViewNode.FLAGS_ASSIST_BLOCKED) == 0;
+ return (mFlags&ViewNode.FLAGS_ASSIST_BLOCKED) != 0;
}
/**
diff --git a/core/java/android/bluetooth/BluetoothDevice.java b/core/java/android/bluetooth/BluetoothDevice.java
index c96fe71..d27dfa0 100644
--- a/core/java/android/bluetooth/BluetoothDevice.java
+++ b/core/java/android/bluetooth/BluetoothDevice.java
@@ -92,7 +92,8 @@ public final class BluetoothDevice implements Parcelable {
* <p>Always contains the extra fields {@link #EXTRA_DEVICE} and {@link
* #EXTRA_CLASS}. Can contain the extra fields {@link #EXTRA_NAME} and/or
* {@link #EXTRA_RSSI} if they are available.
- * <p>Requires {@link android.Manifest.permission#BLUETOOTH} to receive.
+ * <p>Requires {@link android.Manifest.permission#BLUETOOTH} and
+ * {@link android.Manifest.permission#ACCESS_COARSE_LOCATION} to receive.
*/
// TODO: Change API to not broadcast RSSI if not available (incoming connection)
@SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
diff --git a/core/java/android/bluetooth/BluetoothSocket.java b/core/java/android/bluetooth/BluetoothSocket.java
index 6302521..fb81fd1 100644
--- a/core/java/android/bluetooth/BluetoothSocket.java
+++ b/core/java/android/bluetooth/BluetoothSocket.java
@@ -240,6 +240,8 @@ public final class BluetoothSocket implements Closeable {
as.close();
throw new IOException("bt socket acept failed");
}
+
+ as.mPfd = new ParcelFileDescriptor(fds[0]);
as.mSocket = new LocalSocket(fds[0]);
as.mSocketIS = as.mSocket.getInputStream();
as.mSocketOS = as.mSocket.getOutputStream();
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index 675515b..4c7dd10 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -1516,6 +1516,33 @@ public abstract class Context {
public abstract void sendBroadcast(Intent intent,
@Nullable String receiverPermission);
+
+ /**
+ * Broadcast the given intent to all interested BroadcastReceivers, allowing
+ * an array of required permissions to be enforced. This call is asynchronous; it returns
+ * immediately, and you will continue executing while the receivers are run. No results are
+ * propagated from receivers and receivers can not abort the broadcast. If you want to allow
+ * receivers to propagate results or abort the broadcast, you must send an ordered broadcast
+ * using {@link #sendOrderedBroadcast(Intent, String)}.
+ *
+ * <p>See {@link BroadcastReceiver} for more information on Intent broadcasts.
+ *
+ * @param intent The Intent to broadcast; all receivers matching this
+ * Intent will receive the broadcast.
+ * @param receiverPermissions Array of names of permissions that a receiver must hold
+ * in order to receive your broadcast.
+ * If null or empty, no permissions are required.
+ *
+ * @see android.content.BroadcastReceiver
+ * @see #registerReceiver
+ * @see #sendBroadcast(Intent)
+ * @see #sendOrderedBroadcast(Intent, String)
+ * @see #sendOrderedBroadcast(Intent, String, BroadcastReceiver, Handler, int, String, Bundle)
+ * @hide
+ */
+ public abstract void sendBroadcastMultiplePermissions(Intent intent,
+ String[] receiverPermissions);
+
/**
* Broadcast the given intent to all interested BroadcastReceivers, allowing
* an optional required permission to be enforced. This
@@ -1782,6 +1809,17 @@ public abstract class Context {
@Nullable Bundle initialExtras);
/**
+ * Similar to above but takes an appOp as well, to enforce restrictions, and an options Bundle.
+ * @see #sendOrderedBroadcastAsUser(Intent, UserHandle, String,
+ * BroadcastReceiver, Handler, int, String, Bundle)
+ * @hide
+ */
+ public abstract void sendOrderedBroadcastAsUser(Intent intent, UserHandle user,
+ @Nullable String receiverPermission, int appOp, @Nullable Bundle options,
+ BroadcastReceiver resultReceiver, @Nullable Handler scheduler, int initialCode,
+ @Nullable String initialData, @Nullable Bundle initialExtras);
+
+ /**
* <p>Perform a {@link #sendBroadcast(Intent)} that is "sticky," meaning the
* Intent you are sending stays around after the broadcast is complete,
* so that others can quickly retrieve that data through the return
diff --git a/core/java/android/content/ContextWrapper.java b/core/java/android/content/ContextWrapper.java
index 4e7c832..8359edf 100644
--- a/core/java/android/content/ContextWrapper.java
+++ b/core/java/android/content/ContextWrapper.java
@@ -402,6 +402,12 @@ public class ContextWrapper extends Context {
}
/** @hide */
+ @Override
+ public void sendBroadcastMultiplePermissions(Intent intent, String[] receiverPermissions) {
+ mBase.sendBroadcastMultiplePermissions(intent, receiverPermissions);
+ }
+
+ /** @hide */
@SystemApi
@Override
public void sendBroadcast(Intent intent, String receiverPermission, Bundle options) {
@@ -483,12 +489,20 @@ public class ContextWrapper extends Context {
@Override
public void sendOrderedBroadcastAsUser(Intent intent, UserHandle user,
String receiverPermission, int appOp, BroadcastReceiver resultReceiver,
- Handler scheduler,
- int initialCode, String initialData, Bundle initialExtras) {
+ Handler scheduler, int initialCode, String initialData, Bundle initialExtras) {
mBase.sendOrderedBroadcastAsUser(intent, user, receiverPermission, appOp, resultReceiver,
scheduler, initialCode, initialData, initialExtras);
}
+ /** @hide */
+ @Override
+ public void sendOrderedBroadcastAsUser(Intent intent, UserHandle user,
+ String receiverPermission, int appOp, Bundle options, BroadcastReceiver resultReceiver,
+ Handler scheduler, int initialCode, String initialData, Bundle initialExtras) {
+ mBase.sendOrderedBroadcastAsUser(intent, user, receiverPermission, appOp, options,
+ resultReceiver, scheduler, initialCode, initialData, initialExtras);
+ }
+
@Override
@Deprecated
public void sendStickyBroadcast(Intent intent) {
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index c9f9b56..5571662 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -3094,6 +3094,13 @@ public class Intent implements Parcelable, Cloneable {
@SdkConstant(SdkConstantType.INTENT_CATEGORY)
public static final String CATEGORY_HOME = "android.intent.category.HOME";
/**
+ * This is the setup wizard activity, that is the first activity that is displayed
+ * when the user sets up the device for the first time.
+ * @hide
+ */
+ @SdkConstant(SdkConstantType.INTENT_CATEGORY)
+ public static final String CATEGORY_SETUP_WIZARD = "android.intent.category.SETUP_WIZARD";
+ /**
* This activity is a preference panel.
*/
@SdkConstant(SdkConstantType.INTENT_CATEGORY)
diff --git a/core/java/android/content/pm/IPackageManager.aidl b/core/java/android/content/pm/IPackageManager.aidl
index 103ee29..ceb610a 100644
--- a/core/java/android/content/pm/IPackageManager.aidl
+++ b/core/java/android/content/pm/IPackageManager.aidl
@@ -502,9 +502,6 @@ interface IPackageManager {
void addOnPermissionsChangeListener(in IOnPermissionsChangeListener listener);
void removeOnPermissionsChangeListener(in IOnPermissionsChangeListener listener);
-
- int getMountExternalMode(int uid);
-
void grantDefaultPermissionsToEnabledCarrierApps(in String[] packageNames, int userId);
boolean isPermissionRevokedByPolicy(String permission, String packageName, int userId);
diff --git a/core/java/android/content/pm/IntentFilterVerificationInfo.java b/core/java/android/content/pm/IntentFilterVerificationInfo.java
index 96000dd..4dbac05 100644
--- a/core/java/android/content/pm/IntentFilterVerificationInfo.java
+++ b/core/java/android/content/pm/IntentFilterVerificationInfo.java
@@ -26,7 +26,9 @@ import android.os.Parcelable;
import android.text.TextUtils;
import android.util.ArraySet;
import android.util.Log;
+
import com.android.internal.util.XmlUtils;
+
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import org.xmlpull.v1.XmlSerializer;
@@ -181,14 +183,28 @@ public final class IntentFilterVerificationInfo implements Parcelable {
return getStatusStringFromValue(mMainStatus);
}
- public static String getStatusStringFromValue(int val) {
- switch (val) {
- case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK : return "ask";
- case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS : return "always";
- case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER : return "never";
+ public static String getStatusStringFromValue(long val) {
+ StringBuilder sb = new StringBuilder();
+ switch ((int)(val >> 32)) {
+ case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS:
+ sb.append("always : ");
+ sb.append(Long.toHexString(val & 0x00000000FFFFFFFF));
+ break;
+
+ case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK:
+ sb.append("ask");
+ break;
+
+ case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER:
+ sb.append("never");
+ break;
+
+ case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED:
default:
- case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED : return "undefined";
+ sb.append("undefined");
+ break;
}
+ return sb.toString();
}
@Override
diff --git a/core/java/android/content/pm/PackageUserState.java b/core/java/android/content/pm/PackageUserState.java
index 92b8055..9b28401 100644
--- a/core/java/android/content/pm/PackageUserState.java
+++ b/core/java/android/content/pm/PackageUserState.java
@@ -38,6 +38,7 @@ public class PackageUserState {
public ArraySet<String> enabledComponents;
public int domainVerificationStatus;
+ public int appLinkGeneration;
public PackageUserState() {
installed = true;
@@ -60,5 +61,6 @@ public class PackageUserState {
? new ArraySet<>(o.enabledComponents) : null;
blockUninstall = o.blockUninstall;
domainVerificationStatus = o.domainVerificationStatus;
+ appLinkGeneration = o.appLinkGeneration;
}
}
diff --git a/core/java/android/content/res/ColorStateList.java b/core/java/android/content/res/ColorStateList.java
index 579634f..19921b5 100644
--- a/core/java/android/content/res/ColorStateList.java
+++ b/core/java/android/content/res/ColorStateList.java
@@ -603,7 +603,7 @@ public class ColorStateList implements Parcelable {
* @hide only for resource preloading
*/
public ConstantState<ColorStateList> getConstantState() {
- if (mFactory != null) {
+ if (mFactory == null) {
mFactory = new ColorStateListFactory(this);
}
return mFactory;
diff --git a/core/java/android/content/res/Resources.java b/core/java/android/content/res/Resources.java
index 9a99a46..731903c 100644
--- a/core/java/android/content/res/Resources.java
+++ b/core/java/android/content/res/Resources.java
@@ -1918,6 +1918,7 @@ public class Resources {
other.mResId = mResId;
other.mForce = mForce;
other.mCount = mCount;
+ other.mHashCode = mHashCode;
return other;
}
}
diff --git a/core/java/android/hardware/SystemSensorManager.java b/core/java/android/hardware/SystemSensorManager.java
index e7deae8..30cdfd3 100644
--- a/core/java/android/hardware/SystemSensorManager.java
+++ b/core/java/android/hardware/SystemSensorManager.java
@@ -123,7 +123,10 @@ public class SystemSensorManager extends SensorManager {
SensorEventQueue queue = mSensorListeners.get(listener);
if (queue == null) {
Looper looper = (handler != null) ? handler.getLooper() : mMainLooper;
- queue = new SensorEventQueue(listener, looper, this);
+ final String fullClassName = listener.getClass().getEnclosingClass() != null ?
+ listener.getClass().getEnclosingClass().getName() :
+ listener.getClass().getName();
+ queue = new SensorEventQueue(listener, looper, this, fullClassName);
if (!queue.addSensor(sensor, delayUs, maxBatchReportLatencyUs)) {
queue.dispose();
return false;
@@ -166,12 +169,17 @@ public class SystemSensorManager extends SensorManager {
protected boolean requestTriggerSensorImpl(TriggerEventListener listener, Sensor sensor) {
if (sensor == null) throw new IllegalArgumentException("sensor cannot be null");
+ if (listener == null) throw new IllegalArgumentException("listener cannot be null");
+
if (sensor.getReportingMode() != Sensor.REPORTING_MODE_ONE_SHOT) return false;
synchronized (mTriggerListeners) {
TriggerEventQueue queue = mTriggerListeners.get(listener);
if (queue == null) {
- queue = new TriggerEventQueue(listener, mMainLooper, this);
+ final String fullClassName = listener.getClass().getEnclosingClass() != null ?
+ listener.getClass().getEnclosingClass().getName() :
+ listener.getClass().getName();
+ queue = new TriggerEventQueue(listener, mMainLooper, this, fullClassName);
if (!queue.addSensor(sensor, 0, 0)) {
queue.dispose();
return false;
@@ -234,7 +242,8 @@ public class SystemSensorManager extends SensorManager {
}
// Initialize a client for data_injection.
if (mInjectEventQueue == null) {
- mInjectEventQueue = new InjectEventQueue(mMainLooper, this);
+ mInjectEventQueue = new InjectEventQueue(mMainLooper, this,
+ mContext.getPackageName());
}
} else {
// If data injection is being disabled clean up the native resources.
@@ -296,10 +305,11 @@ public class SystemSensorManager extends SensorManager {
protected static final int OPERATING_MODE_NORMAL = 0;
protected static final int OPERATING_MODE_DATA_INJECTION = 1;
- BaseEventQueue(Looper looper, SystemSensorManager manager, int mode) {
+ BaseEventQueue(Looper looper, SystemSensorManager manager, int mode, String packageName) {
+ if (packageName == null) packageName = "";
nSensorEventQueue = nativeInitBaseEventQueue(manager.mNativeInstance,
new WeakReference<>(this), looper.getQueue(), mScratch,
- manager.mContext.getPackageName(), mode, manager.mContext.getOpPackageName());
+ packageName, mode, manager.mContext.getOpPackageName());
mCloseGuard.open("dispose");
mManager = manager;
}
@@ -419,8 +429,8 @@ public class SystemSensorManager extends SensorManager {
private final SparseArray<SensorEvent> mSensorsEvents = new SparseArray<SensorEvent>();
public SensorEventQueue(SensorEventListener listener, Looper looper,
- SystemSensorManager manager) {
- super(looper, manager, OPERATING_MODE_NORMAL);
+ SystemSensorManager manager, String packageName) {
+ super(looper, manager, OPERATING_MODE_NORMAL, packageName);
mListener = listener;
}
@@ -486,8 +496,8 @@ public class SystemSensorManager extends SensorManager {
private final SparseArray<TriggerEvent> mTriggerEvents = new SparseArray<TriggerEvent>();
public TriggerEventQueue(TriggerEventListener listener, Looper looper,
- SystemSensorManager manager) {
- super(looper, manager, OPERATING_MODE_NORMAL);
+ SystemSensorManager manager, String packageName) {
+ super(looper, manager, OPERATING_MODE_NORMAL, packageName);
mListener = listener;
}
@@ -540,8 +550,8 @@ public class SystemSensorManager extends SensorManager {
}
final class InjectEventQueue extends BaseEventQueue {
- public InjectEventQueue(Looper looper, SystemSensorManager manager) {
- super(looper, manager, OPERATING_MODE_DATA_INJECTION);
+ public InjectEventQueue(Looper looper, SystemSensorManager manager, String packageName) {
+ super(looper, manager, OPERATING_MODE_DATA_INJECTION, packageName);
}
int injectSensorData(int handle, float[] values,int accuracy, long timestamp) {
diff --git a/core/java/android/hardware/camera2/CameraCharacteristics.java b/core/java/android/hardware/camera2/CameraCharacteristics.java
index 30aa2d5..5583920 100644
--- a/core/java/android/hardware/camera2/CameraCharacteristics.java
+++ b/core/java/android/hardware/camera2/CameraCharacteristics.java
@@ -1901,7 +1901,7 @@ public final class CameraCharacteristics extends CameraMetadata<CameraCharacteri
* <tbody>
* <tr>
* <td align="center">{@link android.graphics.ImageFormat#JPEG }</td>
- * <td align="center">{@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize}</td>
+ * <td align="center">{@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize} (*1)</td>
* <td align="center">Any</td>
* <td align="center"></td>
* </tr>
@@ -1913,7 +1913,7 @@ public final class CameraCharacteristics extends CameraMetadata<CameraCharacteri
* </tr>
* <tr>
* <td align="center">{@link android.graphics.ImageFormat#JPEG }</td>
- * <td align="center">1280x720 (720)</td>
+ * <td align="center">1280x720 (720p)</td>
* <td align="center">Any</td>
* <td align="center">if 720p &lt;= activeArraySize</td>
* </tr>
@@ -1951,6 +1951,22 @@ public final class CameraCharacteristics extends CameraMetadata<CameraCharacteri
* </table>
* <p>Refer to {@link CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES android.request.availableCapabilities} and {@link android.hardware.camera2.CameraDevice#createCaptureSession } for additional mandatory
* stream configurations on a per-capability basis.</p>
+ * <p>*1: For JPEG format, the sizes may be restricted by below conditions:</p>
+ * <ul>
+ * <li>The HAL may choose the aspect ratio of each Jpeg size to be one of well known ones
+ * (e.g. 4:3, 16:9, 3:2 etc.). If the sensor maximum resolution
+ * (defined by {@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize}) has an aspect ratio other than these,
+ * it does not have to be included in the supported JPEG sizes.</li>
+ * <li>Some hardware JPEG encoders may have pixel boundary alignment requirements, such as
+ * the dimensions being a multiple of 16.
+ * Therefore, the maximum JPEG size may be smaller than sensor maximum resolution.
+ * However, the largest JPEG size will be as close as possible to the sensor maximum
+ * resolution given above constraints. It is required that after aspect ratio adjustments,
+ * additional size reduction due to other issues must be less than 3% in area. For example,
+ * if the sensor maximum resolution is 3280x2464, if the maximum JPEG size has aspect
+ * ratio 4:3, and the JPEG encoder alignment requirement is 16, the maximum JPEG size will be
+ * 3264x2448.</li>
+ * </ul>
* <p>This key is available on all devices.</p>
*
* @see CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL
diff --git a/core/java/android/hardware/camera2/CameraManager.java b/core/java/android/hardware/camera2/CameraManager.java
index 0fb6889..2e4f628 100644
--- a/core/java/android/hardware/camera2/CameraManager.java
+++ b/core/java/android/hardware/camera2/CameraManager.java
@@ -723,6 +723,8 @@ public final class CameraManager {
private static final String TAG = "CameraManagerGlobal";
private final boolean DEBUG = false;
+ private final int CAMERA_SERVICE_RECONNECT_DELAY_MS = 1000;
+
// Singleton instance
private static final CameraManagerGlobal gCameraManager =
new CameraManagerGlobal();
@@ -1158,6 +1160,45 @@ public final class CameraManager {
}
/**
+ * Try to connect to camera service after some delay if any client registered camera
+ * availability callback or torch status callback.
+ */
+ private void scheduleCameraServiceReconnectionLocked() {
+ final Handler handler;
+
+ if (mCallbackMap.size() > 0) {
+ handler = mCallbackMap.valueAt(0);
+ } else if (mTorchCallbackMap.size() > 0) {
+ handler = mTorchCallbackMap.valueAt(0);
+ } else {
+ // Not necessary to reconnect camera service if no client registers a callback.
+ return;
+ }
+
+ if (DEBUG) {
+ Log.v(TAG, "Reconnecting Camera Service in " + CAMERA_SERVICE_RECONNECT_DELAY_MS +
+ " ms");
+ }
+
+ handler.postDelayed(
+ new Runnable() {
+ @Override
+ public void run() {
+ ICameraService cameraService = getCameraService();
+ if (cameraService == null) {
+ synchronized(mLock) {
+ if (DEBUG) {
+ Log.v(TAG, "Reconnecting Camera Service failed.");
+ }
+ scheduleCameraServiceReconnectionLocked();
+ }
+ }
+ }
+ },
+ CAMERA_SERVICE_RECONNECT_DELAY_MS);
+ }
+
+ /**
* Listener for camera service death.
*
* <p>The camera service isn't supposed to die under any normal circumstances, but can be
@@ -1171,21 +1212,19 @@ public final class CameraManager {
mCameraService = null;
- // Tell listeners that the cameras and torch modes are _available_, because any
- // existing clients will have gotten disconnected. This is optimistic under the
- // assumption that the service will be back shortly.
- //
- // Without this, a camera service crash while a camera is open will never signal
- // to listeners that previously in-use cameras are now available.
+ // Tell listeners that the cameras and torch modes are unavailable and schedule a
+ // reconnection to camera service. When camera service is reconnected, the camera
+ // and torch statuses will be updated.
for (int i = 0; i < mDeviceStatus.size(); i++) {
String cameraId = mDeviceStatus.keyAt(i);
- onStatusChangedLocked(STATUS_PRESENT, cameraId);
+ onStatusChangedLocked(STATUS_NOT_PRESENT, cameraId);
}
for (int i = 0; i < mTorchStatus.size(); i++) {
String cameraId = mTorchStatus.keyAt(i);
- onTorchStatusChangedLocked(TORCH_STATUS_AVAILABLE_OFF, cameraId);
+ onTorchStatusChangedLocked(TORCH_STATUS_NOT_AVAILABLE, cameraId);
}
+ scheduleCameraServiceReconnectionLocked();
}
}
diff --git a/core/java/android/hardware/camera2/CameraMetadata.java b/core/java/android/hardware/camera2/CameraMetadata.java
index c8ae5d4..c36683b 100644
--- a/core/java/android/hardware/camera2/CameraMetadata.java
+++ b/core/java/android/hardware/camera2/CameraMetadata.java
@@ -1935,21 +1935,21 @@ public abstract class CameraMetadata<TKey> {
/**
* <p>Same as FACE_PRIORITY scene mode, except that the camera
- * device will choose higher sensivity values ({@link CaptureRequest#SENSOR_SENSITIVITY android.sensor.sensitivity})
+ * device will choose higher sensitivity values ({@link CaptureRequest#SENSOR_SENSITIVITY android.sensor.sensitivity})
* under low light conditions.</p>
* <p>The camera device may be tuned to expose the images in a reduced
* sensitivity range to produce the best quality images. For example,
* if the {@link CameraCharacteristics#SENSOR_INFO_SENSITIVITY_RANGE android.sensor.info.sensitivityRange} gives range of [100, 1600],
* the camera device auto-exposure routine tuning process may limit the actual
- * exposure sensivity range to [100, 1200] to ensure that the noise level isn't
- * exessive to compromise the image quality. Under this situation, the image under
+ * exposure sensitivity range to [100, 1200] to ensure that the noise level isn't
+ * exessive in order to preserve the image quality. Under this situation, the image under
* low light may be under-exposed when the sensor max exposure time (bounded by the
* {@link CaptureRequest#CONTROL_AE_TARGET_FPS_RANGE android.control.aeTargetFpsRange} when {@link CaptureRequest#CONTROL_AE_MODE android.control.aeMode} is one of the
- * ON_* modes) and effecitve max sensitivity are reached. This scene mode allows the
+ * ON_* modes) and effective max sensitivity are reached. This scene mode allows the
* camera device auto-exposure routine to increase the sensitivity up to the max
* sensitivity specified by {@link CameraCharacteristics#SENSOR_INFO_SENSITIVITY_RANGE android.sensor.info.sensitivityRange} when the scene is too
* dark and the max exposure time is reached. The captured images may be noisier
- * compared with the images captured in normal FACE_PRIORITY mode, therefore, it is
+ * compared with the images captured in normal FACE_PRIORITY mode; therefore, it is
* recommended that the application only use this scene mode when it is capable of
* reducing the noise level of the captured images.</p>
* <p>Unlike the other scene modes, {@link CaptureRequest#CONTROL_AE_MODE android.control.aeMode},
diff --git a/core/java/android/hardware/usb/IUsbManager.aidl b/core/java/android/hardware/usb/IUsbManager.aidl
index 0fe112c..80c7b1a 100644
--- a/core/java/android/hardware/usb/IUsbManager.aidl
+++ b/core/java/android/hardware/usb/IUsbManager.aidl
@@ -19,6 +19,8 @@ package android.hardware.usb;
import android.app.PendingIntent;
import android.hardware.usb.UsbAccessory;
import android.hardware.usb.UsbDevice;
+import android.hardware.usb.UsbPort;
+import android.hardware.usb.UsbPortStatus;
import android.os.Bundle;
import android.os.ParcelFileDescriptor;
@@ -108,4 +110,13 @@ interface IUsbManager
/* Clear public keys installed for secure USB debugging */
void clearUsbDebuggingKeys();
+
+ /* Gets the list of USB ports. */
+ UsbPort[] getPorts();
+
+ /* Gets the status of the specified USB port. */
+ UsbPortStatus getPortStatus(in String portId);
+
+ /* Sets the port's current role. */
+ void setPortRoles(in String portId, int powerRole, int dataRole);
}
diff --git a/core/java/android/hardware/usb/UsbManager.java b/core/java/android/hardware/usb/UsbManager.java
index f58b9d6..c88f213 100644
--- a/core/java/android/hardware/usb/UsbManager.java
+++ b/core/java/android/hardware/usb/UsbManager.java
@@ -17,6 +17,8 @@
package android.hardware.usb;
+import com.android.internal.util.Preconditions;
+
import android.app.PendingIntent;
import android.content.Context;
import android.os.Bundle;
@@ -74,6 +76,22 @@ public class UsbManager {
public static final String ACTION_USB_STATE =
"android.hardware.usb.action.USB_STATE";
+ /**
+ * Broadcast Action: A broadcast for USB port changes.
+ *
+ * This intent is sent when a USB port is added, removed, or changes state.
+ * <ul>
+ * <li> {@link #EXTRA_PORT} containing the {@link android.hardware.usb.UsbPort}
+ * for the port.
+ * <li> {@link #EXTRA_PORT_STATUS} containing the {@link android.hardware.usb.UsbPortStatus}
+ * for the port, or null if the port has been removed
+ * </ul>
+ *
+ * @hide
+ */
+ public static final String ACTION_USB_PORT_CHANGED =
+ "android.hardware.usb.action.USB_PORT_CHANGED";
+
/**
* Broadcast Action: A broadcast for USB device attached event.
*
@@ -214,6 +232,23 @@ public class UsbManager {
public static final String USB_FUNCTION_ACCESSORY = "accessory";
/**
+ * Name of extra for {@link #ACTION_USB_PORT_CHANGED}
+ * containing the {@link UsbPort} object for the port.
+ *
+ * @hide
+ */
+ public static final String EXTRA_PORT = "port";
+
+ /**
+ * Name of extra for {@link #ACTION_USB_PORT_CHANGED}
+ * containing the {@link UsbPortStatus} object for the port, or null if the port
+ * was removed.
+ *
+ * @hide
+ */
+ public static final String EXTRA_PORT_STATUS = "portStatus";
+
+ /**
* Name of extra for {@link #ACTION_USB_DEVICE_ATTACHED} and
* {@link #ACTION_USB_DEVICE_DETACHED} broadcasts
* containing the {@link UsbDevice} object for the device.
@@ -499,6 +534,77 @@ public class UsbManager {
return false;
}
+ /**
+ * Returns a list of physical USB ports on the device.
+ * <p>
+ * This list is guaranteed to contain all dual-role USB Type C ports but it might
+ * be missing other ports depending on whether the kernel USB drivers have been
+ * updated to publish all of the device's ports through the new "dual_role_usb"
+ * device class (which supports all types of ports despite its name).
+ * </p>
+ *
+ * @return The list of USB ports, or null if none.
+ *
+ * @hide
+ */
+ public UsbPort[] getPorts() {
+ try {
+ return mService.getPorts();
+ } catch (RemoteException e) {
+ Log.e(TAG, "RemoteException in getPorts", e);
+ }
+ return null;
+ }
+
+ /**
+ * Gets the status of the specified USB port.
+ *
+ * @param port The port to query.
+ * @return The status of the specified USB port, or null if unknown.
+ *
+ * @hide
+ */
+ public UsbPortStatus getPortStatus(UsbPort port) {
+ Preconditions.checkNotNull(port, "port must not be null");
+
+ try {
+ return mService.getPortStatus(port.getId());
+ } catch (RemoteException e) {
+ Log.e(TAG, "RemoteException in getPortStatus", e);
+ }
+ return null;
+ }
+
+ /**
+ * Sets the desired role combination of the port.
+ * <p>
+ * The supported role combinations depend on what is connected to the port and may be
+ * determined by consulting
+ * {@link UsbPortStatus#isRoleCombinationSupported UsbPortStatus.isRoleCombinationSupported}.
+ * </p><p>
+ * Note: This function is asynchronous and may fail silently without applying
+ * the requested changes. If this function does cause a status change to occur then
+ * a {@link #ACTION_USB_PORT_CHANGED} broadcast will be sent.
+ * </p>
+ *
+ * @param powerRole The desired power role: {@link UsbPort#POWER_ROLE_SOURCE}
+ * or {@link UsbPort#POWER_ROLE_SINK}, or 0 if no power role.
+ * @param dataRole The desired data role: {@link UsbPort#DATA_ROLE_HOST}
+ * or {@link UsbPort#DATA_ROLE_DEVICE}, or 0 if no data role.
+ *
+ * @hide
+ */
+ public void setPortRoles(UsbPort port, int powerRole, int dataRole) {
+ Preconditions.checkNotNull(port, "port must not be null");
+ UsbPort.checkRoles(powerRole, dataRole);
+
+ try {
+ mService.setPortRoles(port.getId(), powerRole, dataRole);
+ } catch (RemoteException e) {
+ Log.e(TAG, "RemoteException in setPortRole", e);
+ }
+ }
+
/** @hide */
public static String addFunction(String functions, String function) {
if ("none".equals(functions)) {
diff --git a/core/java/android/hardware/usb/UsbPort.aidl b/core/java/android/hardware/usb/UsbPort.aidl
new file mode 100644
index 0000000..b7a7920
--- /dev/null
+++ b/core/java/android/hardware/usb/UsbPort.aidl
@@ -0,0 +1,19 @@
+/*
+ * Copyright (C) 2015, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.usb;
+
+parcelable UsbPort;
diff --git a/core/java/android/hardware/usb/UsbPort.java b/core/java/android/hardware/usb/UsbPort.java
new file mode 100644
index 0000000..c9a4e9b
--- /dev/null
+++ b/core/java/android/hardware/usb/UsbPort.java
@@ -0,0 +1,238 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.usb;
+
+import com.android.internal.util.Preconditions;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+
+/**
+ * Represents a physical USB port and describes its characteristics.
+ * <p>
+ * This object is immutable.
+ * </p>
+ *
+ * @hide
+ */
+public final class UsbPort implements Parcelable {
+ private final String mId;
+ private final int mSupportedModes;
+
+ /**
+ * Mode bit: This USB port can act as a downstream facing port (host).
+ * <p>
+ * Implies that the port supports the {@link #POWER_ROLE_SOURCE} and {@link #DATA_ROLE_HOST}
+ * combination of roles (and possibly others as well).
+ * </p>
+ */
+ public static final int MODE_DFP = 1 << 0;
+
+ /**
+ * Mode bit: This USB port can act as an upstream facing port (device).
+ * <p>
+ * Implies that the port supports the {@link #POWER_ROLE_SINK} and {@link #DATA_ROLE_DEVICE}
+ * combination of roles (and possibly others as well).
+ * </p>
+ */
+ public static final int MODE_UFP = 1 << 1;
+
+ /**
+ * Mode bit: This USB port can act either as an downstream facing port (host) or as
+ * an upstream facing port (device).
+ * <p>
+ * Implies that the port supports the {@link #POWER_ROLE_SOURCE} and {@link #DATA_ROLE_HOST}
+ * combination of roles and the {@link #POWER_ROLE_SINK} and {@link #DATA_ROLE_DEVICE}
+ * combination of roles (and possibly others as well).
+ * </p>
+ */
+ public static final int MODE_DUAL = MODE_DFP | MODE_UFP;
+
+ /**
+ * Power role: This USB port can act as a source (provide power).
+ */
+ public static final int POWER_ROLE_SOURCE = 1;
+
+ /**
+ * Power role: This USB port can act as a sink (receive power).
+ */
+ public static final int POWER_ROLE_SINK = 2;
+
+ /**
+ * Data role: This USB port can act as a host (access data services).
+ */
+ public static final int DATA_ROLE_HOST = 1;
+
+ /**
+ * Data role: This USB port can act as a device (offer data services).
+ */
+ public static final int DATA_ROLE_DEVICE = 2;
+
+ private static final int NUM_DATA_ROLES = 3;
+
+ /** @hide */
+ public UsbPort(String id, int supportedModes) {
+ mId = id;
+ mSupportedModes = supportedModes;
+ }
+
+ /**
+ * Gets the unique id of the port.
+ *
+ * @return The unique id of the port; not intended for display.
+ */
+ public String getId() {
+ return mId;
+ }
+
+ /**
+ * Gets the supported modes of the port.
+ * <p>
+ * The actual mode of the port may vary depending on what is plugged into it.
+ * </p>
+ *
+ * @return The supported modes: one of {@link #MODE_DFP}, {@link #MODE_UFP}, or
+ * {@link #MODE_DUAL}.
+ */
+ public int getSupportedModes() {
+ return mSupportedModes;
+ }
+
+ /**
+ * Combines one power and one data role together into a unique value with
+ * exactly one bit set. This can be used to efficiently determine whether
+ * a combination of roles is supported by testing whether that bit is present
+ * in a bit-field.
+ *
+ * @param powerRole The desired power role: {@link UsbPort#POWER_ROLE_SOURCE}
+ * or {@link UsbPort#POWER_ROLE_SINK}, or 0 if no power role.
+ * @param dataRole The desired data role: {@link UsbPort#DATA_ROLE_HOST}
+ * or {@link UsbPort#DATA_ROLE_DEVICE}, or 0 if no data role.
+ * @hide
+ */
+ public static int combineRolesAsBit(int powerRole, int dataRole) {
+ checkRoles(powerRole, dataRole);
+ final int index = powerRole * NUM_DATA_ROLES + dataRole;
+ return 1 << index;
+ }
+
+ /** @hide */
+ public static String modeToString(int mode) {
+ switch (mode) {
+ case 0:
+ return "none";
+ case MODE_DFP:
+ return "dfp";
+ case MODE_UFP:
+ return "ufp";
+ case MODE_DUAL:
+ return "dual";
+ default:
+ return Integer.toString(mode);
+ }
+ }
+
+ /** @hide */
+ public static String powerRoleToString(int role) {
+ switch (role) {
+ case 0:
+ return "no-power";
+ case POWER_ROLE_SOURCE:
+ return "source";
+ case POWER_ROLE_SINK:
+ return "sink";
+ default:
+ return Integer.toString(role);
+ }
+ }
+
+ /** @hide */
+ public static String dataRoleToString(int role) {
+ switch (role) {
+ case 0:
+ return "no-data";
+ case DATA_ROLE_HOST:
+ return "host";
+ case DATA_ROLE_DEVICE:
+ return "device";
+ default:
+ return Integer.toString(role);
+ }
+ }
+
+ /** @hide */
+ public static String roleCombinationsToString(int combo) {
+ StringBuilder result = new StringBuilder();
+ result.append("[");
+
+ boolean first = true;
+ while (combo != 0) {
+ final int index = Integer.numberOfTrailingZeros(combo);
+ combo &= ~(1 << index);
+ final int powerRole = index / NUM_DATA_ROLES;
+ final int dataRole = index % NUM_DATA_ROLES;
+ if (first) {
+ first = false;
+ } else {
+ result.append(", ");
+ }
+ result.append(powerRoleToString(powerRole));
+ result.append(':');
+ result.append(dataRoleToString(dataRole));
+ }
+
+ result.append("]");
+ return result.toString();
+ }
+
+ /** @hide */
+ public static void checkRoles(int powerRole, int dataRole) {
+ Preconditions.checkArgumentInRange(powerRole, 0, POWER_ROLE_SINK, "powerRole");
+ Preconditions.checkArgumentInRange(dataRole, 0, DATA_ROLE_DEVICE, "dataRole");
+ }
+
+ @Override
+ public String toString() {
+ return "UsbPort{id=" + mId + ", supportedModes=" + modeToString(mSupportedModes) + "}";
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ dest.writeString(mId);
+ dest.writeInt(mSupportedModes);
+ }
+
+ public static final Parcelable.Creator<UsbPort> CREATOR =
+ new Parcelable.Creator<UsbPort>() {
+ @Override
+ public UsbPort createFromParcel(Parcel in) {
+ String id = in.readString();
+ int supportedModes = in.readInt();
+ return new UsbPort(id, supportedModes);
+ }
+
+ @Override
+ public UsbPort[] newArray(int size) {
+ return new UsbPort[size];
+ }
+ };
+}
diff --git a/core/java/android/hardware/usb/UsbPortStatus.aidl b/core/java/android/hardware/usb/UsbPortStatus.aidl
new file mode 100644
index 0000000..9a7e468
--- /dev/null
+++ b/core/java/android/hardware/usb/UsbPortStatus.aidl
@@ -0,0 +1,19 @@
+/*
+ * Copyright (C) 2015, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.usb;
+
+parcelable UsbPortStatus;
diff --git a/core/java/android/hardware/usb/UsbPortStatus.java b/core/java/android/hardware/usb/UsbPortStatus.java
new file mode 100644
index 0000000..5c0e81a
--- /dev/null
+++ b/core/java/android/hardware/usb/UsbPortStatus.java
@@ -0,0 +1,144 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.usb;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+
+/**
+ * Describes the status of a USB port.
+ * <p>
+ * This object is immutable.
+ * </p>
+ *
+ * @hide
+ */
+public final class UsbPortStatus implements Parcelable {
+ private final int mCurrentMode;
+ private final int mCurrentPowerRole;
+ private final int mCurrentDataRole;
+ private final int mSupportedRoleCombinations;
+
+ /** @hide */
+ public UsbPortStatus(int currentMode, int currentPowerRole, int currentDataRole,
+ int supportedRoleCombinations) {
+ mCurrentMode = currentMode;
+ mCurrentPowerRole = currentPowerRole;
+ mCurrentDataRole = currentDataRole;
+ mSupportedRoleCombinations = supportedRoleCombinations;
+ }
+
+ /**
+ * Returns true if there is anything connected to the port.
+ *
+ * @return True if there is anything connected to the port.
+ */
+ public boolean isConnected() {
+ return mCurrentMode != 0;
+ }
+
+ /**
+ * Gets the current mode of the port.
+ *
+ * @return The current mode: {@link UsbPort#MODE_DFP}, {@link UsbPort#MODE_UFP},
+ * or 0 if nothing is connected.
+ */
+ public int getCurrentMode() {
+ return mCurrentMode;
+ }
+
+ /**
+ * Gets the current power role of the port.
+ *
+ * @return The current power role: {@link UsbPort#POWER_ROLE_SOURCE},
+ * {@link UsbPort#POWER_ROLE_SINK}, or 0 if nothing is connected.
+ */
+ public int getCurrentPowerRole() {
+ return mCurrentPowerRole;
+ }
+
+ /**
+ * Gets the current data role of the port.
+ *
+ * @return The current data role: {@link UsbPort#DATA_ROLE_HOST},
+ * {@link UsbPort#DATA_ROLE_DEVICE}, or 0 if nothing is connected.
+ */
+ public int getCurrentDataRole() {
+ return mCurrentDataRole;
+ }
+
+ /**
+ * Returns true if the specified power and data role combination is supported
+ * given what is currently connected to the port.
+ *
+ * @param powerRole The power role to check: {@link UsbPort#POWER_ROLE_SOURCE}
+ * or {@link UsbPort#POWER_ROLE_SINK}, or 0 if no power role.
+ * @param dataRole The data role to check: either {@link UsbPort#DATA_ROLE_HOST}
+ * or {@link UsbPort#DATA_ROLE_DEVICE}, or 0 if no data role.
+ */
+ public boolean isRoleCombinationSupported(int powerRole, int dataRole) {
+ return (mSupportedRoleCombinations &
+ UsbPort.combineRolesAsBit(powerRole, dataRole)) != 0;
+ }
+
+ /** @hide */
+ public int getSupportedRoleCombinations() {
+ return mSupportedRoleCombinations;
+ }
+
+ @Override
+ public String toString() {
+ return "UsbPortStatus{connected=" + isConnected()
+ + ", currentMode=" + UsbPort.modeToString(mCurrentMode)
+ + ", currentPowerRole=" + UsbPort.powerRoleToString(mCurrentPowerRole)
+ + ", currentDataRole=" + UsbPort.dataRoleToString(mCurrentDataRole)
+ + ", supportedRoleCombinations="
+ + UsbPort.roleCombinationsToString(mSupportedRoleCombinations)
+ + "}";
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ dest.writeInt(mCurrentMode);
+ dest.writeInt(mCurrentPowerRole);
+ dest.writeInt(mCurrentDataRole);
+ dest.writeInt(mSupportedRoleCombinations);
+ }
+
+ public static final Parcelable.Creator<UsbPortStatus> CREATOR =
+ new Parcelable.Creator<UsbPortStatus>() {
+ @Override
+ public UsbPortStatus createFromParcel(Parcel in) {
+ int currentMode = in.readInt();
+ int currentPowerRole = in.readInt();
+ int currentDataRole = in.readInt();
+ int supportedRoleCombinations = in.readInt();
+ return new UsbPortStatus(currentMode, currentPowerRole, currentDataRole,
+ supportedRoleCombinations);
+ }
+
+ @Override
+ public UsbPortStatus[] newArray(int size) {
+ return new UsbPortStatus[size];
+ }
+ };
+}
diff --git a/core/java/android/inputmethodservice/ExtractEditText.java b/core/java/android/inputmethodservice/ExtractEditText.java
index 8bc2876..b039fc7 100644
--- a/core/java/android/inputmethodservice/ExtractEditText.java
+++ b/core/java/android/inputmethodservice/ExtractEditText.java
@@ -29,7 +29,7 @@ import android.widget.EditText;
public class ExtractEditText extends EditText {
private InputMethodService mIME;
private int mSettingExtractedText;
-
+
public ExtractEditText(Context context) {
super(context, null);
}
@@ -45,11 +45,11 @@ public class ExtractEditText extends EditText {
public ExtractEditText(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
}
-
+
void setIME(InputMethodService ime) {
mIME = ime;
}
-
+
/**
* Start making changes that will not be reported to the client. That
* is, {@link #onSelectionChanged(int, int)} will not result in sending
@@ -58,7 +58,7 @@ public class ExtractEditText extends EditText {
public void startInternalChanges() {
mSettingExtractedText += 1;
}
-
+
/**
* Finish making changes that will not be reported to the client. That
* is, {@link #onSelectionChanged(int, int)} will not result in sending
@@ -67,7 +67,7 @@ public class ExtractEditText extends EditText {
public void finishInternalChanges() {
mSettingExtractedText -= 1;
}
-
+
/**
* Implement just to keep track of when we are setting text from the
* client (vs. seeing changes in ourself from the user).
@@ -80,7 +80,7 @@ public class ExtractEditText extends EditText {
mSettingExtractedText--;
}
}
-
+
/**
* Report to the underlying text editor about selection changes.
*/
@@ -89,7 +89,7 @@ public class ExtractEditText extends EditText {
mIME.onExtractedSelectionChanged(selStart, selEnd);
}
}
-
+
/**
* Redirect clicks to the IME for handling there. First allows any
* on click handler to run, though.
@@ -101,17 +101,18 @@ public class ExtractEditText extends EditText {
}
return false;
}
-
+
@Override public boolean onTextContextMenuItem(int id) {
- if (mIME != null && mIME.onExtractTextContextMenuItem(id)) {
+ // Select all shouldn't be handled by the original edit text, but by the extracted one.
+ if (id != android.R.id.selectAll && mIME != null && mIME.onExtractTextContextMenuItem(id)) {
// Mode was started on Extracted, needs to be stopped here.
- // Cut and paste will change the text, which stops selection mode.
- if (id == android.R.id.copy) stopTextActionMode();
+ // Cut will change the text, which stops selection mode.
+ if (id == android.R.id.copy || id == android.R.id.paste) stopTextActionMode();
return true;
}
return super.onTextContextMenuItem(id);
}
-
+
/**
* We are always considered to be an input method target.
*/
@@ -119,14 +120,14 @@ public class ExtractEditText extends EditText {
public boolean isInputMethodTarget() {
return true;
}
-
+
/**
* Return true if the edit text is currently showing a scroll bar.
*/
public boolean hasVerticalScrollBar() {
return computeVerticalScrollRange() > computeVerticalScrollExtent();
}
-
+
/**
* Pretend like the window this view is in always has focus, so its
* highlight and cursor will be displayed.
diff --git a/core/java/android/net/IConnectivityManager.aidl b/core/java/android/net/IConnectivityManager.aidl
index 78f8b95..46c28a6 100644
--- a/core/java/android/net/IConnectivityManager.aidl
+++ b/core/java/android/net/IConnectivityManager.aidl
@@ -112,7 +112,7 @@ interface IConnectivityManager
void startLegacyVpn(in VpnProfile profile);
- LegacyVpnInfo getLegacyVpnInfo();
+ LegacyVpnInfo getLegacyVpnInfo(int userId);
VpnInfo[] getAllVpnInfo();
diff --git a/core/java/android/os/BatteryStats.java b/core/java/android/os/BatteryStats.java
index adc84bc..ecb7f5a 100644
--- a/core/java/android/os/BatteryStats.java
+++ b/core/java/android/os/BatteryStats.java
@@ -1193,9 +1193,13 @@ public abstract class BatteryStats implements Parcelable {
public static final int EVENT_PACKAGE_INACTIVE = 0x000f;
// Event for a package becoming active due to an interaction.
public static final int EVENT_PACKAGE_ACTIVE = 0x0010;
+ // Event for a package being on the temporary whitelist.
+ public static final int EVENT_TEMP_WHITELIST = 0x0011;
+ // Event for the screen waking up.
+ public static final int EVENT_SCREEN_WAKE_UP = 0x0012;
// Number of event types.
- public static final int EVENT_COUNT = 0x0011;
+ public static final int EVENT_COUNT = 0x0013;
// Mask to extract out only the type part of the event.
public static final int EVENT_TYPE_MASK = ~(EVENT_FLAG_START|EVENT_FLAG_FINISH);
@@ -1219,6 +1223,10 @@ public abstract class BatteryStats implements Parcelable {
EVENT_USER_FOREGROUND | EVENT_FLAG_FINISH;
public static final int EVENT_ALARM_START = EVENT_ALARM | EVENT_FLAG_START;
public static final int EVENT_ALARM_FINISH = EVENT_ALARM | EVENT_FLAG_FINISH;
+ public static final int EVENT_TEMP_WHITELIST_START =
+ EVENT_TEMP_WHITELIST | EVENT_FLAG_START;
+ public static final int EVENT_TEMP_WHITELIST_FINISH =
+ EVENT_TEMP_WHITELIST | EVENT_FLAG_FINISH;
// For CMD_EVENT.
public int eventCode;
@@ -1852,12 +1860,14 @@ public abstract class BatteryStats implements Parcelable {
public static final String[] HISTORY_EVENT_NAMES = new String[] {
"null", "proc", "fg", "top", "sync", "wake_lock_in", "job", "user", "userfg", "conn",
- "active", "pkginst", "pkgunin", "alarm", "stats", "inactive", "active"
+ "active", "pkginst", "pkgunin", "alarm", "stats", "inactive", "active", "tmpwhitelist",
+ "screenwake",
};
public static final String[] HISTORY_EVENT_CHECKIN_NAMES = new String[] {
"Enl", "Epr", "Efg", "Etp", "Esy", "Ewl", "Ejb", "Eur", "Euf", "Ecn",
- "Eac", "Epi", "Epu", "Eal", "Est", "Eai", "Eaa"
+ "Eac", "Epi", "Epu", "Eal", "Est", "Eai", "Eaa", "Etw",
+ "Esw",
};
/**
diff --git a/core/java/android/os/IDeviceIdleController.aidl b/core/java/android/os/IDeviceIdleController.aidl
index fe4aa13..b768852 100644
--- a/core/java/android/os/IDeviceIdleController.aidl
+++ b/core/java/android/os/IDeviceIdleController.aidl
@@ -27,6 +27,7 @@ interface IDeviceIdleController {
int[] getAppIdWhitelist();
int[] getAppIdTempWhitelist();
boolean isPowerSaveWhitelistApp(String name);
- void addPowerSaveTempWhitelistApp(String name, long duration, int userId);
+ void addPowerSaveTempWhitelistApp(String name, long duration, int userId, String reason);
+ long addPowerSaveTempWhitelistAppForMms(String name, int userId, String reason);
void exitIdle(String reason);
}
diff --git a/core/java/android/os/IPowerManager.aidl b/core/java/android/os/IPowerManager.aidl
index 804d3d0..0f37ac7 100644
--- a/core/java/android/os/IPowerManager.aidl
+++ b/core/java/android/os/IPowerManager.aidl
@@ -37,7 +37,7 @@ interface IPowerManager
boolean isWakeLockLevelSupported(int level);
void userActivity(long time, int event, int flags);
- void wakeUp(long time);
+ void wakeUp(long time, String reason, String opPackageName);
void goToSleep(long time, int reason, int flags);
void nap(long time);
boolean isInteractive();
diff --git a/core/java/android/os/PowerManager.java b/core/java/android/os/PowerManager.java
index 6ef1cd0..9a1a03e 100644
--- a/core/java/android/os/PowerManager.java
+++ b/core/java/android/os/PowerManager.java
@@ -658,7 +658,17 @@ public final class PowerManager {
*/
public void wakeUp(long time) {
try {
- mService.wakeUp(time);
+ mService.wakeUp(time, "wakeUp", mContext.getOpPackageName());
+ } catch (RemoteException e) {
+ }
+ }
+
+ /**
+ * @hide
+ */
+ public void wakeUp(long time, String reason) {
+ try {
+ mService.wakeUp(time, reason, mContext.getOpPackageName());
} catch (RemoteException e) {
}
}
diff --git a/core/java/android/os/storage/IMountService.java b/core/java/android/os/storage/IMountService.java
index 84a879c..c3b098b 100644
--- a/core/java/android/os/storage/IMountService.java
+++ b/core/java/android/os/storage/IMountService.java
@@ -758,13 +758,15 @@ public interface IMountService extends IInterface {
return _result;
}
- public StorageVolume[] getVolumeList(int userId) throws RemoteException {
+ public StorageVolume[] getVolumeList(int uid, String packageName)
+ throws RemoteException {
Parcel _data = Parcel.obtain();
Parcel _reply = Parcel.obtain();
StorageVolume[] _result;
try {
_data.writeInterfaceToken(DESCRIPTOR);
- _data.writeInt(userId);
+ _data.writeInt(uid);
+ _data.writeString(packageName);
mRemote.transact(Stub.TRANSACTION_getVolumeList, _data, _reply, 0);
_reply.readException();
_result = _reply.createTypedArray(StorageVolume.CREATOR);
@@ -1177,21 +1179,6 @@ public interface IMountService extends IInterface {
_data.recycle();
}
}
-
- @Override
- public void remountUid(int uid) throws RemoteException {
- Parcel _data = Parcel.obtain();
- Parcel _reply = Parcel.obtain();
- try {
- _data.writeInterfaceToken(DESCRIPTOR);
- _data.writeInt(uid);
- mRemote.transact(Stub.TRANSACTION_remountUid, _data, _reply, 0);
- _reply.readException();
- } finally {
- _reply.recycle();
- _data.recycle();
- }
- }
}
private static final String DESCRIPTOR = "IMountService";
@@ -1307,8 +1294,6 @@ public interface IMountService extends IInterface {
static final int TRANSACTION_benchmark = IBinder.FIRST_CALL_TRANSACTION + 59;
static final int TRANSACTION_setDebugFlags = IBinder.FIRST_CALL_TRANSACTION + 60;
- static final int TRANSACTION_remountUid = IBinder.FIRST_CALL_TRANSACTION + 61;
-
/**
* Cast an IBinder object into an IMountService interface, generating a
* proxy if needed.
@@ -1622,8 +1607,9 @@ public interface IMountService extends IInterface {
}
case TRANSACTION_getVolumeList: {
data.enforceInterface(DESCRIPTOR);
- int userId = data.readInt();
- StorageVolume[] result = getVolumeList(userId);
+ int uid = data.readInt();
+ String packageName = data.readString();
+ StorageVolume[] result = getVolumeList(uid, packageName);
reply.writeNoException();
reply.writeTypedArray(result, android.os.Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
return true;
@@ -1862,13 +1848,6 @@ public interface IMountService extends IInterface {
reply.writeNoException();
return true;
}
- case TRANSACTION_remountUid: {
- data.enforceInterface(DESCRIPTOR);
- int uid = data.readInt();
- remountUid(uid);
- reply.writeNoException();
- return true;
- }
}
return super.onTransact(code, data, reply, flags);
}
@@ -2080,11 +2059,11 @@ public interface IMountService extends IInterface {
/**
* Returns list of all mountable volumes.
*/
- public StorageVolume[] getVolumeList(int userId) throws RemoteException;
+ public StorageVolume[] getVolumeList(int uid, String packageName) throws RemoteException;
/**
* Gets the path on the filesystem for the ASEC container itself.
- *
+ *
* @param cid ASEC container ID
* @return path to filesystem or {@code null} if it's not found
* @throws RemoteException
@@ -2178,6 +2157,4 @@ public interface IMountService extends IInterface {
public String getPrimaryStorageUuid() throws RemoteException;
public void setPrimaryStorageUuid(String volumeUuid, IPackageMoveObserver callback)
throws RemoteException;
-
- public void remountUid(int uid) throws RemoteException;
}
diff --git a/core/java/android/os/storage/MountServiceInternal.java b/core/java/android/os/storage/MountServiceInternal.java
new file mode 100644
index 0000000..17aaef9
--- /dev/null
+++ b/core/java/android/os/storage/MountServiceInternal.java
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.os.storage;
+
+/**
+ * Mount service local interface.
+ *
+ * @hide Only for use within the system server.
+ */
+public abstract class MountServiceInternal {
+
+ /**
+ * Policy that influences how external storage is mounted and reported.
+ */
+ public interface ExternalStorageMountPolicy {
+ /**
+ * Gets the external storage mount mode for the given uid.
+ *
+ * @param uid The UID for which to determine mount mode.
+ * @param packageName The package in the UID for making the call.
+ * @return The mount mode.
+ *
+ * @see com.android.internal.os.Zygote#MOUNT_EXTERNAL_NONE
+ * @see com.android.internal.os.Zygote#MOUNT_EXTERNAL_DEFAULT
+ * @see com.android.internal.os.Zygote#MOUNT_EXTERNAL_READ
+ * @see com.android.internal.os.Zygote#MOUNT_EXTERNAL_WRITE
+ */
+ public int getMountMode(int uid, String packageName);
+
+ /**
+ * Gets whether external storage should be reported to the given UID.
+ *
+ * @param uid The UID for which to determine whether it has external storage.
+ * @param packageName The package in the UID for making the call.
+ * @return Weather to report external storage.
+ * @return True to report the state of external storage, false to
+ * report it as unmounted.
+ */
+ public boolean hasExternalStorage(int uid, String packageName);
+ }
+
+ /**
+ * Adds a policy for determining how external storage is mounted and reported.
+ * The mount mode is the most conservative result from querying all registered
+ * policies. Similarly, the reported state is the most conservative result from
+ * querying all registered policies.
+ *
+ * @param policy The policy to add.
+ */
+ public abstract void addExternalStoragePolicy(ExternalStorageMountPolicy policy);
+
+ /**
+ * Notify the mount service that the mount policy for a UID changed.
+ * @param uid The UID for which policy changed.
+ * @param packageName The package in the UID for making the call.
+ */
+ public abstract void onExternalStoragePolicyChanged(int uid, String packageName);
+
+ /**
+ * Gets the mount mode to use for a given UID as determined by consultin all
+ * policies.
+ *
+ * @param uid The UID for which to get mount mode.
+ * @param packageName The package in the UID for making the call.
+ * @return The mount mode.
+ */
+ public abstract int getExternalStorageMountMode(int uid, String packageName);
+}
diff --git a/core/java/android/os/storage/StorageManager.java b/core/java/android/os/storage/StorageManager.java
index f03e04e..b2cec60 100644
--- a/core/java/android/os/storage/StorageManager.java
+++ b/core/java/android/os/storage/StorageManager.java
@@ -20,6 +20,7 @@ import static android.net.TrafficStats.MB_IN_BYTES;
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.app.ActivityThread;
import android.content.ContentResolver;
import android.content.Context;
import android.content.pm.IPackageMoveObserver;
@@ -816,17 +817,19 @@ public class StorageManager {
/** {@hide} */
private static @Nullable StorageVolume getStorageVolume(StorageVolume[] volumes, File file) {
- File canonicalFile = null;
try {
- canonicalFile = file.getCanonicalFile();
+ file = file.getCanonicalFile();
} catch (IOException ignored) {
- canonicalFile = null;
+ return null;
}
for (StorageVolume volume : volumes) {
- if (volume.getPathFile().equals(file)) {
- return volume;
+ File volumeFile = volume.getPathFile();
+ try {
+ volumeFile = volumeFile.getCanonicalFile();
+ } catch (IOException ignored) {
+ continue;
}
- if (FileUtils.contains(volume.getPathFile(), canonicalFile)) {
+ if (FileUtils.contains(volumeFile, file)) {
return volume;
}
}
@@ -857,7 +860,24 @@ public class StorageManager {
final IMountService mountService = IMountService.Stub.asInterface(
ServiceManager.getService("mount"));
try {
- return mountService.getVolumeList(userId);
+ String packageName = ActivityThread.currentOpPackageName();
+ if (packageName == null) {
+ // Package name can be null if the activity thread is running but the app
+ // hasn't bound yet. In this case we fall back to the first package in the
+ // current UID. This works for runtime permissions as permission state is
+ // per UID and permission realted app ops are updated for all UID packages.
+ String[] packageNames = ActivityThread.getPackageManager().getPackagesForUid(
+ android.os.Process.myUid());
+ if (packageNames == null || packageNames.length <= 0) {
+ return new StorageVolume[0];
+ }
+ packageName = packageNames[0];
+ }
+ final int uid = ActivityThread.getPackageManager().getPackageUid(packageName, userId);
+ if (uid <= 0) {
+ return new StorageVolume[0];
+ }
+ return mountService.getVolumeList(uid, packageName);
} catch (RemoteException e) {
throw e.rethrowAsRuntimeException();
}
@@ -894,15 +914,6 @@ public class StorageManager {
}
/** {@hide} */
- public void remountUid(int uid) {
- try {
- mMountService.remountUid(uid);
- } catch (RemoteException e) {
- throw e.rethrowAsRuntimeException();
- }
- }
-
- /** {@hide} */
private static final int DEFAULT_THRESHOLD_PERCENTAGE = 10;
private static final long DEFAULT_THRESHOLD_MAX_BYTES = 500 * MB_IN_BYTES;
private static final long DEFAULT_FULL_THRESHOLD_BYTES = MB_IN_BYTES;
@@ -956,7 +967,7 @@ public class StorageManager {
|| vol.getType() == VolumeInfo.TYPE_PUBLIC) && vol.isMountedReadable()) {
final File internalPath = FileUtils.rewriteAfterRename(vol.getPath(),
vol.getInternalPath(), path);
- if (internalPath != null) {
+ if (internalPath != null && internalPath.exists()) {
return internalPath;
}
}
diff --git a/core/java/android/os/storage/VolumeInfo.java b/core/java/android/os/storage/VolumeInfo.java
index 32f7bc9..8d603a1 100644
--- a/core/java/android/os/storage/VolumeInfo.java
+++ b/core/java/android/os/storage/VolumeInfo.java
@@ -298,14 +298,14 @@ public class VolumeInfo implements Parcelable {
}
}
- public StorageVolume buildStorageVolume(Context context, int userId) {
+ public StorageVolume buildStorageVolume(Context context, int userId, boolean reportUnmounted) {
final StorageManager storage = context.getSystemService(StorageManager.class);
final boolean removable;
final boolean emulated;
final boolean allowMassStorage = false;
- final String envState = getEnvironmentForState(state);
-
+ final String envState = reportUnmounted
+ ? Environment.MEDIA_UNMOUNTED : getEnvironmentForState(state);
File userPath = getPathForUser(userId);
if (userPath == null) {
userPath = new File("/dev/null");
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 4e13758..fff355b 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -574,7 +574,22 @@ public final class Settings {
*/
@SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
public static final String ACTION_MANAGE_OVERLAY_PERMISSION =
- "android.settings.MANAGE_OVERLAY_PERMISSION";
+ "android.settings.action.MANAGE_OVERLAY_PERMISSION";
+
+ /**
+ * Activity Action: Show settings to toggle apps' capablity to
+ * to read/write system settings.
+ * <p>
+ * In some cases, a matching Activity may not exist, so ensure you
+ * safeguard against this.
+ * <p>
+ * Input: Nothing.
+ * <p>
+ * Output: Nothing.
+ */
+ @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
+ public static final String ACTION_MANAGE_WRITE_SETTINGS =
+ "android.settings.action.MANAGE_WRITE_SETTINGS";
/**
* Activity Action: Show screen of details about a particular application.
diff --git a/core/java/android/service/dreams/Sandman.java b/core/java/android/service/dreams/Sandman.java
index 5f5b079..eeb340b 100644
--- a/core/java/android/service/dreams/Sandman.java
+++ b/core/java/android/service/dreams/Sandman.java
@@ -92,7 +92,8 @@ public final class Sandman {
// be awake by the time this happens. Otherwise the dream may not start.
PowerManager powerManager =
(PowerManager)context.getSystemService(Context.POWER_SERVICE);
- powerManager.wakeUp(SystemClock.uptimeMillis());
+ powerManager.wakeUp(SystemClock.uptimeMillis(),
+ "android.service.dreams:DREAM");
} else {
Slog.i(TAG, "Activating dream by user request.");
}
diff --git a/core/java/android/service/voice/VoiceInteractionService.java b/core/java/android/service/voice/VoiceInteractionService.java
index 549c93e..479c9e2 100644
--- a/core/java/android/service/voice/VoiceInteractionService.java
+++ b/core/java/android/service/voice/VoiceInteractionService.java
@@ -37,7 +37,6 @@ import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.util.Locale;
-
/**
* Top-level service of the current global voice interactor, which is providing
* support for hotwording, the back-end of a {@link android.app.VoiceInteractor}, etc.
@@ -154,11 +153,39 @@ public class VoiceInteractionService extends Service {
}
/**
+ * Set contextual options you would always like to have disabled when a session
+ * is shown. The flags may be any combination of
+ * {@link VoiceInteractionSession#SHOW_WITH_ASSIST VoiceInteractionSession.SHOW_WITH_ASSIST} and
+ * {@link VoiceInteractionSession#SHOW_WITH_SCREENSHOT
+ * VoiceInteractionSession.SHOW_WITH_SCREENSHOT}.
+ */
+ public void setDisabledShowContext(int flags) {
+ try {
+ mSystemService.setDisabledShowContext(flags);
+ } catch (RemoteException e) {
+ }
+ }
+
+ /**
+ * Return the value set by {@link #setDisabledShowContext}.
+ */
+ public int getDisabledShowContext() {
+ try {
+ return mSystemService.getDisabledShowContext();
+ } catch (RemoteException e) {
+ return 0;
+ }
+ }
+
+ /**
* Request that the associated {@link android.service.voice.VoiceInteractionSession} be
* shown to the user, starting it if necessary.
* @param args Arbitrary arguments that will be propagated to the session.
* @param flags Indicates additional optional behavior that should be performed. May
- * be {@link VoiceInteractionSession#SHOW_WITH_ASSIST VoiceInteractionSession.SHOW_WITH_ASSIST}
+ * be any combination of
+ * {@link VoiceInteractionSession#SHOW_WITH_ASSIST VoiceInteractionSession.SHOW_WITH_ASSIST} and
+ * {@link VoiceInteractionSession#SHOW_WITH_SCREENSHOT
+ * VoiceInteractionSession.SHOW_WITH_SCREENSHOT}
* to request that the system generate and deliver assist data on the current foreground
* app as part of showing the session UI.
*/
diff --git a/core/java/android/service/voice/VoiceInteractionSession.java b/core/java/android/service/voice/VoiceInteractionSession.java
index e408b36..95f96e8 100644
--- a/core/java/android/service/voice/VoiceInteractionSession.java
+++ b/core/java/android/service/voice/VoiceInteractionSession.java
@@ -650,7 +650,7 @@ public class VoiceInteractionSession implements KeyEvent.Callback, ComponentCall
class MyCallbacks implements HandlerCaller.Callback, SoftInputWindow.Callback {
@Override
public void executeMessage(Message msg) {
- SomeArgs args;
+ SomeArgs args = null;
switch (msg.what) {
case MSG_START_CONFIRMATION:
if (DEBUG) Log.d(TAG, "onConfirm: req=" + msg.obj);
@@ -676,6 +676,8 @@ public class VoiceInteractionSession implements KeyEvent.Callback, ComponentCall
args = (SomeArgs)msg.obj;
if (DEBUG) Log.d(TAG, "onGetSupportedCommands: cmds=" + args.arg1);
args.arg1 = onGetSupportedCommands((String[]) args.arg1);
+ args.complete();
+ args = null;
break;
case MSG_CANCEL:
if (DEBUG) Log.d(TAG, "onCancel: req=" + ((Request)msg.obj));
@@ -723,6 +725,9 @@ public class VoiceInteractionSession implements KeyEvent.Callback, ComponentCall
doHide();
break;
}
+ if (args != null) {
+ args.recycle();
+ }
}
@Override
@@ -908,12 +913,38 @@ public class VoiceInteractionSession implements KeyEvent.Callback, ComponentCall
}
/**
+ * Equivalent to {@link VoiceInteractionService#setDisabledShowContext
+ * VoiceInteractionService.setDisabledShowContext(int)}.
+ */
+ public void setDisabledShowContext(int flags) {
+ try {
+ mSystemService.setDisabledShowContext(flags);
+ } catch (RemoteException e) {
+ }
+ }
+
+ /**
+ * Equivalent to {@link VoiceInteractionService#getDisabledShowContext
+ * VoiceInteractionService.getDisabledShowContext}.
+ */
+ public int getDisabledShowContext() {
+ try {
+ return mSystemService.getDisabledShowContext();
+ } catch (RemoteException e) {
+ return 0;
+ }
+ }
+
+ /**
* Show the UI for this session. This asks the system to go through the process of showing
* your UI, which will eventually culminate in {@link #onShow}. This is similar to calling
* {@link VoiceInteractionService#showSession VoiceInteractionService.showSession}.
* @param args Arbitrary arguments that will be propagated {@link #onShow}.
* @param flags Indicates additional optional behavior that should be performed. May
- * be {@link VoiceInteractionSession#SHOW_WITH_ASSIST VoiceInteractionSession.SHOW_WITH_ASSIST}
+ * be any combination of
+ * {@link VoiceInteractionSession#SHOW_WITH_ASSIST VoiceInteractionSession.SHOW_WITH_ASSIST} and
+ * {@link VoiceInteractionSession#SHOW_WITH_SCREENSHOT
+ * VoiceInteractionSession.SHOW_WITH_SCREENSHOT}
* to request that the system generate and deliver assist data on the current foreground
* app as part of showing the session UI.
*/
diff --git a/core/java/android/text/Html.java b/core/java/android/text/Html.java
index a55a08c..dc1d6f6 100644
--- a/core/java/android/text/Html.java
+++ b/core/java/android/text/Html.java
@@ -137,7 +137,12 @@ public class Html {
}
/**
- * Returns an HTML representation of the provided Spanned text.
+ * Returns an HTML representation of the provided Spanned text. A best effort is
+ * made to add HTML tags corresponding to spans. Also note that HTML metacharacters
+ * (such as "&lt;" and "&amp;") within the input text are escaped.
+ *
+ * @param text input text to convert
+ * @return string containing input converted to HTML
*/
public static String toHtml(Spanned text) {
StringBuilder out = new StringBuilder();
diff --git a/core/java/android/text/SpannableStringInternal.java b/core/java/android/text/SpannableStringInternal.java
index d114d32..5c5deb4 100644
--- a/core/java/android/text/SpannableStringInternal.java
+++ b/core/java/android/text/SpannableStringInternal.java
@@ -214,10 +214,6 @@ import java.lang.reflect.Array;
Object ret1 = null;
for (int i = 0; i < spanCount; i++) {
- if (kind != null && !kind.isInstance(spans[i])) {
- continue;
- }
-
int spanStart = data[i * COLUMNS + START];
int spanEnd = data[i * COLUMNS + END];
@@ -237,6 +233,11 @@ import java.lang.reflect.Array;
}
}
+ // verify span class as late as possible, since it is expensive
+ if (kind != null && !kind.isInstance(spans[i])) {
+ continue;
+ }
+
if (count == 0) {
ret1 = spans[i];
count++;
diff --git a/core/java/android/util/LocalLog.java b/core/java/android/util/LocalLog.java
index 4862f01..39f66a5 100644
--- a/core/java/android/util/LocalLog.java
+++ b/core/java/android/util/LocalLog.java
@@ -55,6 +55,12 @@ public final class LocalLog {
}
}
+ public synchronized void reverseDump(FileDescriptor fd, PrintWriter pw, String[] args) {
+ for (int i = mLog.size() - 1; i >= 0; i--) {
+ pw.println(mLog.get(i));
+ }
+ }
+
public static class ReadOnlyLocalLog {
private final LocalLog mLog;
ReadOnlyLocalLog(LocalLog log) {
diff --git a/core/java/android/widget/AppSecurityPermissions.java b/core/java/android/widget/AppSecurityPermissions.java
index d1af9dc..e3ce6f2 100644
--- a/core/java/android/widget/AppSecurityPermissions.java
+++ b/core/java/android/widget/AppSecurityPermissions.java
@@ -61,8 +61,6 @@ import java.util.Set;
*/
public class AppSecurityPermissions {
- public static final int WHICH_PERSONAL = 1<<0;
- public static final int WHICH_DEVICE = 1<<1;
public static final int WHICH_NEW = 1<<2;
public static final int WHICH_ALL = 0xffff;
@@ -75,7 +73,8 @@ public class AppSecurityPermissions {
= new HashMap<String, MyPermissionGroupInfo>();
private final List<MyPermissionGroupInfo> mPermGroupsList
= new ArrayList<MyPermissionGroupInfo>();
- private final PermissionGroupInfoComparator mPermGroupComparator = new PermissionGroupInfoComparator();
+ private final PermissionGroupInfoComparator mPermGroupComparator =
+ new PermissionGroupInfoComparator();
private final PermissionInfoComparator mPermComparator = new PermissionInfoComparator();
private final List<MyPermissionInfo> mPermsList = new ArrayList<MyPermissionInfo>();
private final CharSequence mNewPermPrefix;
@@ -85,8 +84,6 @@ public class AppSecurityPermissions {
CharSequence mLabel;
final ArrayList<MyPermissionInfo> mNewPermissions = new ArrayList<MyPermissionInfo>();
- final ArrayList<MyPermissionInfo> mPersonalPermissions = new ArrayList<MyPermissionInfo>();
- final ArrayList<MyPermissionInfo> mDevicePermissions = new ArrayList<MyPermissionInfo>();
final ArrayList<MyPermissionInfo> mAllPermissions = new ArrayList<MyPermissionInfo>();
MyPermissionGroupInfo(PermissionInfo perm) {
@@ -352,13 +349,6 @@ public class AppSecurityPermissions {
}
for (int i=0; i<strList.length; i++) {
String permName = strList[i];
- // If we are only looking at an existing app, then we only
- // care about permissions that have actually been granted to it.
- if (installedPkgInfo != null && info != installedPkgInfo) {
- if ((flagsList[i]&PackageInfo.REQUESTED_PERMISSION_GRANTED) == 0) {
- continue;
- }
- }
try {
PermissionInfo tmpPermInfo = mPm.getPermissionInfo(permName, 0);
if (tmpPermInfo == null) {
@@ -431,10 +421,6 @@ public class AppSecurityPermissions {
private List<MyPermissionInfo> getPermissionList(MyPermissionGroupInfo grp, int which) {
if (which == WHICH_NEW) {
return grp.mNewPermissions;
- } else if (which == WHICH_PERSONAL) {
- return grp.mPersonalPermissions;
- } else if (which == WHICH_DEVICE) {
- return grp.mDevicePermissions;
} else {
return grp.mAllPermissions;
}
@@ -577,15 +563,8 @@ public class AppSecurityPermissions {
private static class PermissionGroupInfoComparator implements Comparator<MyPermissionGroupInfo> {
private final Collator sCollator = Collator.getInstance();
- PermissionGroupInfoComparator() {
- }
+ @Override
public final int compare(MyPermissionGroupInfo a, MyPermissionGroupInfo b) {
- if (((a.flags^b.flags)&PermissionGroupInfo.FLAG_PERSONAL_INFO) != 0) {
- return ((a.flags&PermissionGroupInfo.FLAG_PERSONAL_INFO) != 0) ? -1 : 1;
- }
- if (a.priority != b.priority) {
- return a.priority > b.priority ? -1 : 1;
- }
return sCollator.compare(a.mLabel, b.mLabel);
}
}
@@ -628,11 +607,6 @@ public class AppSecurityPermissions {
if (pInfo.mNew) {
addPermToList(group.mNewPermissions, pInfo);
}
- if ((group.flags&PermissionGroupInfo.FLAG_PERSONAL_INFO) != 0) {
- addPermToList(group.mPersonalPermissions, pInfo);
- } else {
- addPermToList(group.mDevicePermissions, pInfo);
- }
}
}
}
@@ -652,12 +626,5 @@ public class AppSecurityPermissions {
mPermGroupsList.add(pgrp);
}
Collections.sort(mPermGroupsList, mPermGroupComparator);
- if (localLOGV) {
- for (MyPermissionGroupInfo grp : mPermGroupsList) {
- Log.i(TAG, "Group " + grp.name + " personal="
- + ((grp.flags&PermissionGroupInfo.FLAG_PERSONAL_INFO) != 0)
- + " priority=" + grp.priority);
- }
- }
}
}
diff --git a/core/java/android/widget/Editor.java b/core/java/android/widget/Editor.java
index 96e033a..d897f49 100644
--- a/core/java/android/widget/Editor.java
+++ b/core/java/android/widget/Editor.java
@@ -16,6 +16,12 @@
package android.widget;
+import java.text.BreakIterator;
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.List;
+
import android.R;
import android.annotation.Nullable;
import android.app.PendingIntent;
@@ -106,12 +112,6 @@ import com.android.internal.util.GrowingArrayUtils;
import com.android.internal.util.Preconditions;
import com.android.internal.widget.EditableInputConnection;
-import java.text.BreakIterator;
-import java.util.Arrays;
-import java.util.Comparator;
-import java.util.HashMap;
-import java.util.List;
-
/**
* Helper class used by TextView to handle editable text views.
@@ -127,6 +127,7 @@ public class Editor {
private static int DRAG_SHADOW_MAX_TEXT_LENGTH = 20;
private static final float LINE_SLOP_MULTIPLIER_FOR_HANDLEVIEWS = 0.5f;
private static final int UNSET_X_VALUE = -1;
+ private static final int UNSET_LINE = -1;
// Tag used when the Editor maintains its own separate UndoManager.
private static final String UNDO_OWNER_TAG = "Editor";
@@ -3510,7 +3511,11 @@ public class Editor {
// Minimum touch target size for handles
private int mMinSize;
// Indicates the line of text that the handle is on.
- protected int mPrevLine = -1;
+ protected int mPrevLine = UNSET_LINE;
+ // Indicates the line of text that the user was touching. This can differ from mPrevLine
+ // when selecting text when the handles jump to the end / start of words which may be on
+ // a different line.
+ protected int mPreviousLineTouched = UNSET_LINE;
public HandleView(Drawable drawableLtr, Drawable drawableRtl) {
super(mTextView.getContext());
@@ -3801,6 +3806,7 @@ public class Editor {
mLastParentX = positionListener.getPositionX();
mLastParentY = positionListener.getPositionY();
mIsDragging = true;
+ mPreviousLineTouched = UNSET_LINE;
break;
}
@@ -4015,8 +4021,12 @@ public class Editor {
Layout layout = mTextView.getLayout();
int offset;
if (layout != null) {
- int currLine = getCurrentLineAdjustedForSlop(layout, mPrevLine, y);
+ if (mPreviousLineTouched == UNSET_LINE) {
+ mPreviousLineTouched = mTextView.getLineAtCoordinate(y);
+ }
+ int currLine = getCurrentLineAdjustedForSlop(layout, mPreviousLineTouched, y);
offset = mTextView.getOffsetAtCoordinate(currLine, x);
+ mPreviousLineTouched = currLine;
} else {
offset = mTextView.getOffsetForPosition(x, y);
}
@@ -4092,9 +4102,13 @@ public class Editor {
return;
}
+ if (mPreviousLineTouched == UNSET_LINE) {
+ mPreviousLineTouched = mTextView.getLineAtCoordinate(y);
+ }
+
boolean positionCursor = false;
final int selectionEnd = mTextView.getSelectionEnd();
- int currLine = getCurrentLineAdjustedForSlop(layout, mPrevLine, y);
+ int currLine = getCurrentLineAdjustedForSlop(layout, mPreviousLineTouched, y);
int initialOffset = mTextView.getOffsetAtCoordinate(currLine, x);
if (initialOffset >= selectionEnd) {
@@ -4138,9 +4152,9 @@ public class Editor {
} else {
final float xDiff = x - mPrevX;
if (atRtl) {
- isExpanding = xDiff > 0 || currLine > mPrevLine;
+ isExpanding = xDiff > 0 || currLine > mPreviousLineTouched;
} else {
- isExpanding = xDiff < 0 || currLine < mPrevLine;
+ isExpanding = xDiff < 0 || currLine < mPreviousLineTouched;
}
}
@@ -4204,6 +4218,7 @@ public class Editor {
offset = getNextCursorOffset(selectionEnd, false);
mTouchWordDelta = 0.0f;
}
+ mPreviousLineTouched = currLine;
positionAtCursorOffset(offset, false);
}
mPrevX = x;
@@ -4218,8 +4233,9 @@ public class Editor {
@Override
public boolean onTouchEvent(MotionEvent event) {
boolean superResult = super.onTouchEvent(event);
- if (event.getActionMasked() == MotionEvent.ACTION_UP) {
- // Reset the touch word offset when the user has lifted their finger.
+ if (event.getActionMasked() == MotionEvent.ACTION_DOWN) {
+ // Reset the touch word offset and x value when the user
+ // re-engages the handle.
mTouchWordDelta = 0.0f;
mPrevX = UNSET_X_VALUE;
}
@@ -4280,9 +4296,13 @@ public class Editor {
return;
}
+ if (mPreviousLineTouched == UNSET_LINE) {
+ mPreviousLineTouched = mTextView.getLineAtCoordinate(y);
+ }
+
boolean positionCursor = false;
final int selectionStart = mTextView.getSelectionStart();
- int currLine = getCurrentLineAdjustedForSlop(layout, mPrevLine, y);
+ int currLine = getCurrentLineAdjustedForSlop(layout, mPreviousLineTouched, y);
int initialOffset = mTextView.getOffsetAtCoordinate(currLine, x);
if (initialOffset <= selectionStart) {
@@ -4326,9 +4346,9 @@ public class Editor {
} else {
final float xDiff = x - mPrevX;
if (atRtl) {
- isExpanding = xDiff < 0 || currLine < mPrevLine;
+ isExpanding = xDiff < 0 || currLine < mPreviousLineTouched;
} else {
- isExpanding = xDiff > 0 || currLine > mPrevLine;
+ isExpanding = xDiff > 0 || currLine > mPreviousLineTouched;
}
}
@@ -4392,6 +4412,7 @@ public class Editor {
offset = getNextCursorOffset(selectionStart, true);
mTouchWordDelta = 0.0f;
}
+ mPreviousLineTouched = currLine;
positionAtCursorOffset(offset, false);
}
mPrevX = x;
@@ -4406,8 +4427,9 @@ public class Editor {
@Override
public boolean onTouchEvent(MotionEvent event) {
boolean superResult = super.onTouchEvent(event);
- if (event.getActionMasked() == MotionEvent.ACTION_UP) {
- // Reset the touch word offset when the user has lifted their finger.
+ if (event.getActionMasked() == MotionEvent.ACTION_DOWN) {
+ // Reset the touch word offset and x value when the user
+ // re-engages the handle.
mTouchWordDelta = 0.0f;
mPrevX = UNSET_X_VALUE;
}
@@ -4416,10 +4438,16 @@ public class Editor {
}
private int getCurrentLineAdjustedForSlop(Layout layout, int prevLine, float y) {
+ final int trueLine = mTextView.getLineAtCoordinate(y);
if (layout == null || prevLine > layout.getLineCount()
|| layout.getLineCount() <= 0 || prevLine < 0) {
// Invalid parameters, just return whatever line is at y.
- return mTextView.getLineAtCoordinate(y);
+ return trueLine;
+ }
+
+ if (Math.abs(trueLine - prevLine) >= 2) {
+ // Only stick to lines if we're within a line of the previous selection.
+ return trueLine;
}
final float verticalOffset = mTextView.viewportToContentVerticalOffset();
diff --git a/core/java/android/widget/Switch.java b/core/java/android/widget/Switch.java
index f45e750..e672fc3 100644
--- a/core/java/android/widget/Switch.java
+++ b/core/java/android/widget/Switch.java
@@ -62,7 +62,7 @@ import com.android.internal.R;
* {@link #setTextAppearance(android.content.Context, int) textAppearance} and the related
* setTypeface() methods control the typeface and style of label text, whereas the
* {@link #setSwitchTextAppearance(android.content.Context, int) switchTextAppearance} and
- * the related seSwitchTypeface() methods control that of the thumb.
+ * the related setSwitchTypeface() methods control that of the thumb.
*
* <p>See the <a href="{@docRoot}guide/topics/ui/controls/togglebutton.html">Toggle Buttons</a>
* guide.</p>
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index 42ac599..131ba46 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -6347,17 +6347,28 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
if (text.text != null) {
if (content == null) {
setText(text.text, TextView.BufferType.EDITABLE);
- } else if (text.partialStartOffset < 0) {
- removeParcelableSpans(content, 0, content.length());
- content.replace(0, content.length(), text.text);
} else {
- final int N = content.length();
- int start = text.partialStartOffset;
- if (start > N) start = N;
- int end = text.partialEndOffset;
- if (end > N) end = N;
+ int start = 0;
+ int end = content.length();
+
+ if (text.partialStartOffset >= 0) {
+ final int N = content.length();
+ start = text.partialStartOffset;
+ if (start > N) start = N;
+ end = text.partialEndOffset;
+ if (end > N) end = N;
+ }
+
removeParcelableSpans(content, start, end);
- content.replace(start, end, text.text);
+ if (TextUtils.equals(content.subSequence(start, end), text.text)) {
+ if (text.text instanceof Spanned) {
+ // OK to copy spans only.
+ TextUtils.copySpansFrom((Spanned) text.text, start, end,
+ Object.class, content, start);
+ }
+ } else {
+ content.replace(start, end, text.text);
+ }
}
}