Merge "Make sure top activity is stopped on sleep if paused." into oc-mr1-dev
diff --git a/api/test-current.txt b/api/test-current.txt
index 62f8885..9487740 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -12093,6 +12093,18 @@
ctor public SQLiteFullException(java.lang.String);
}
+ public final class SQLiteGlobal {
+ method public static java.lang.String getDefaultJournalMode();
+ method public static int getDefaultPageSize();
+ method public static java.lang.String getDefaultSyncMode();
+ method public static int getIdleConnectionTimeout();
+ method public static int getJournalSizeLimit();
+ method public static int getWALAutoCheckpoint();
+ method public static int getWALConnectionPoolSize();
+ method public static java.lang.String getWALSyncMode();
+ method public static int releaseMemory();
+ }
+
public class SQLiteMisuseException extends android.database.sqlite.SQLiteException {
ctor public SQLiteMisuseException();
ctor public SQLiteMisuseException(java.lang.String);
diff --git a/core/java/android/bluetooth/BluetoothA2dpSink.java b/core/java/android/bluetooth/BluetoothA2dpSink.java
index 9dfc4b4..4ebef4f 100755
--- a/core/java/android/bluetooth/BluetoothA2dpSink.java
+++ b/core/java/android/bluetooth/BluetoothA2dpSink.java
@@ -125,7 +125,7 @@
private Context mContext;
private ServiceListener mServiceListener;
- private IBluetoothA2dpSink mService;
+ private volatile IBluetoothA2dpSink mService;
private BluetoothAdapter mAdapter;
final private IBluetoothStateChangeCallback mBluetoothStateChangeCallback =
@@ -239,16 +239,16 @@
*/
public boolean connect(BluetoothDevice device) {
if (DBG) log("connect(" + device + ")");
- if (mService != null && isEnabled() &&
- isValidDevice(device)) {
+ final IBluetoothA2dpSink service = mService;
+ if (service != null && isEnabled() && isValidDevice(device)) {
try {
- return mService.connect(device);
+ return service.connect(device);
} catch (RemoteException e) {
Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
return false;
}
}
- if (mService == null) Log.w(TAG, "Proxy not attached to service");
+ if (service == null) Log.w(TAG, "Proxy not attached to service");
return false;
}
@@ -280,16 +280,16 @@
*/
public boolean disconnect(BluetoothDevice device) {
if (DBG) log("disconnect(" + device + ")");
- if (mService != null && isEnabled() &&
- isValidDevice(device)) {
+ final IBluetoothA2dpSink service = mService;
+ if (service != null && isEnabled() && isValidDevice(device)) {
try {
- return mService.disconnect(device);
+ return service.disconnect(device);
} catch (RemoteException e) {
Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
return false;
}
}
- if (mService == null) Log.w(TAG, "Proxy not attached to service");
+ if (service == null) Log.w(TAG, "Proxy not attached to service");
return false;
}
@@ -298,15 +298,16 @@
*/
public List<BluetoothDevice> getConnectedDevices() {
if (VDBG) log("getConnectedDevices()");
- if (mService != null && isEnabled()) {
+ final IBluetoothA2dpSink service = mService;
+ if (service != null && isEnabled()) {
try {
- return mService.getConnectedDevices();
+ return service.getConnectedDevices();
} catch (RemoteException e) {
Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
return new ArrayList<BluetoothDevice>();
}
}
- if (mService == null) Log.w(TAG, "Proxy not attached to service");
+ if (service == null) Log.w(TAG, "Proxy not attached to service");
return new ArrayList<BluetoothDevice>();
}
@@ -315,15 +316,16 @@
*/
public List<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states) {
if (VDBG) log("getDevicesMatchingStates()");
- if (mService != null && isEnabled()) {
+ final IBluetoothA2dpSink service = mService;
+ if (service != null && isEnabled()) {
try {
- return mService.getDevicesMatchingConnectionStates(states);
+ return service.getDevicesMatchingConnectionStates(states);
} catch (RemoteException e) {
Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
return new ArrayList<BluetoothDevice>();
}
}
- if (mService == null) Log.w(TAG, "Proxy not attached to service");
+ if (service == null) Log.w(TAG, "Proxy not attached to service");
return new ArrayList<BluetoothDevice>();
}
@@ -332,16 +334,16 @@
*/
public int getConnectionState(BluetoothDevice device) {
if (VDBG) log("getState(" + device + ")");
- if (mService != null && isEnabled()
- && isValidDevice(device)) {
+ final IBluetoothA2dpSink service = mService;
+ if (service != null && isEnabled() && isValidDevice(device)) {
try {
- return mService.getConnectionState(device);
+ return service.getConnectionState(device);
} catch (RemoteException e) {
Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
return BluetoothProfile.STATE_DISCONNECTED;
}
}
- if (mService == null) Log.w(TAG, "Proxy not attached to service");
+ if (service == null) Log.w(TAG, "Proxy not attached to service");
return BluetoothProfile.STATE_DISCONNECTED;
}
@@ -358,16 +360,16 @@
*/
public BluetoothAudioConfig getAudioConfig(BluetoothDevice device) {
if (VDBG) log("getAudioConfig(" + device + ")");
- if (mService != null && isEnabled()
- && isValidDevice(device)) {
+ final IBluetoothA2dpSink service = mService;
+ if (service != null && isEnabled() && isValidDevice(device)) {
try {
- return mService.getAudioConfig(device);
+ return service.getAudioConfig(device);
} catch (RemoteException e) {
Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
return null;
}
}
- if (mService == null) Log.w(TAG, "Proxy not attached to service");
+ if (service == null) Log.w(TAG, "Proxy not attached to service");
return null;
}
@@ -388,21 +390,21 @@
*/
public boolean setPriority(BluetoothDevice device, int priority) {
if (DBG) log("setPriority(" + device + ", " + priority + ")");
- if (mService != null && isEnabled()
- && isValidDevice(device)) {
- if (priority != BluetoothProfile.PRIORITY_OFF &&
- priority != BluetoothProfile.PRIORITY_ON){
+ final IBluetoothA2dpSink service = mService;
+ if (service != null && isEnabled() && isValidDevice(device)) {
+ if (priority != BluetoothProfile.PRIORITY_OFF
+ && priority != BluetoothProfile.PRIORITY_ON) {
return false;
}
try {
- return mService.setPriority(device, priority);
+ return service.setPriority(device, priority);
} catch (RemoteException e) {
Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
return false;
}
}
- if (mService == null) Log.w(TAG, "Proxy not attached to service");
- return false;
+ if (service == null) Log.w(TAG, "Proxy not attached to service");
+ return false;
}
/**
@@ -420,16 +422,16 @@
*/
public int getPriority(BluetoothDevice device) {
if (VDBG) log("getPriority(" + device + ")");
- if (mService != null && isEnabled()
- && isValidDevice(device)) {
+ final IBluetoothA2dpSink service = mService;
+ if (service != null && isEnabled() && isValidDevice(device)) {
try {
- return mService.getPriority(device);
+ return service.getPriority(device);
} catch (RemoteException e) {
Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
return BluetoothProfile.PRIORITY_OFF;
}
}
- if (mService == null) Log.w(TAG, "Proxy not attached to service");
+ if (service == null) Log.w(TAG, "Proxy not attached to service");
return BluetoothProfile.PRIORITY_OFF;
}
@@ -441,16 +443,16 @@
* @param device BluetoothDevice device
*/
public boolean isA2dpPlaying(BluetoothDevice device) {
- if (mService != null && isEnabled()
- && isValidDevice(device)) {
+ final IBluetoothA2dpSink service = mService;
+ if (service != null && isEnabled() && isValidDevice(device)) {
try {
- return mService.isA2dpPlaying(device);
+ return service.isA2dpPlaying(device);
} catch (RemoteException e) {
Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
return false;
}
}
- if (mService == null) Log.w(TAG, "Proxy not attached to service");
+ if (service == null) Log.w(TAG, "Proxy not attached to service");
return false;
}
@@ -483,7 +485,6 @@
public void onServiceConnected(ComponentName className, IBinder service) {
if (DBG) Log.d(TAG, "Proxy object connected");
mService = IBluetoothA2dpSink.Stub.asInterface(Binder.allowBlocking(service));
-
if (mServiceListener != null) {
mServiceListener.onServiceConnected(BluetoothProfile.A2DP_SINK,
BluetoothA2dpSink.this);
@@ -499,15 +500,11 @@
};
private boolean isEnabled() {
- if (mAdapter.getState() == BluetoothAdapter.STATE_ON) return true;
- return false;
+ return mAdapter.getState() == BluetoothAdapter.STATE_ON;
}
- private boolean isValidDevice(BluetoothDevice device) {
- if (device == null) return false;
-
- if (BluetoothAdapter.checkBluetoothAddress(device.getAddress())) return true;
- return false;
+ private static boolean isValidDevice(BluetoothDevice device) {
+ return device != null && BluetoothAdapter.checkBluetoothAddress(device.getAddress());
}
private static void log(String msg) {
diff --git a/core/java/android/bluetooth/BluetoothAvrcpController.java b/core/java/android/bluetooth/BluetoothAvrcpController.java
index 0261b1b..a04f110 100644
--- a/core/java/android/bluetooth/BluetoothAvrcpController.java
+++ b/core/java/android/bluetooth/BluetoothAvrcpController.java
@@ -20,8 +20,6 @@
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
-import android.media.MediaMetadata;
-import android.media.session.PlaybackState;
import android.os.Binder;
import android.os.IBinder;
import android.os.RemoteException;
@@ -83,7 +81,7 @@
private Context mContext;
private ServiceListener mServiceListener;
- private IBluetoothAvrcpController mService;
+ private volatile IBluetoothAvrcpController mService;
private BluetoothAdapter mAdapter;
final private IBluetoothStateChangeCallback mBluetoothStateChangeCallback =
@@ -180,15 +178,16 @@
*/
public List<BluetoothDevice> getConnectedDevices() {
if (VDBG) log("getConnectedDevices()");
- if (mService != null && isEnabled()) {
+ final IBluetoothAvrcpController service = mService;
+ if (service != null && isEnabled()) {
try {
- return mService.getConnectedDevices();
+ return service.getConnectedDevices();
} catch (RemoteException e) {
Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
return new ArrayList<BluetoothDevice>();
}
}
- if (mService == null) Log.w(TAG, "Proxy not attached to service");
+ if (service == null) Log.w(TAG, "Proxy not attached to service");
return new ArrayList<BluetoothDevice>();
}
@@ -197,15 +196,16 @@
*/
public List<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states) {
if (VDBG) log("getDevicesMatchingStates()");
- if (mService != null && isEnabled()) {
+ final IBluetoothAvrcpController service = mService;
+ if (service != null && isEnabled()) {
try {
- return mService.getDevicesMatchingConnectionStates(states);
+ return service.getDevicesMatchingConnectionStates(states);
} catch (RemoteException e) {
Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
return new ArrayList<BluetoothDevice>();
}
}
- if (mService == null) Log.w(TAG, "Proxy not attached to service");
+ if (service == null) Log.w(TAG, "Proxy not attached to service");
return new ArrayList<BluetoothDevice>();
}
@@ -214,16 +214,16 @@
*/
public int getConnectionState(BluetoothDevice device) {
if (VDBG) log("getState(" + device + ")");
- if (mService != null && isEnabled()
- && isValidDevice(device)) {
+ final IBluetoothAvrcpController service = mService;
+ if (service != null && isEnabled() && isValidDevice(device)) {
try {
- return mService.getConnectionState(device);
+ return service.getConnectionState(device);
} catch (RemoteException e) {
Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
return BluetoothProfile.STATE_DISCONNECTED;
}
}
- if (mService == null) Log.w(TAG, "Proxy not attached to service");
+ if (service == null) Log.w(TAG, "Proxy not attached to service");
return BluetoothProfile.STATE_DISCONNECTED;
}
@@ -235,9 +235,10 @@
public BluetoothAvrcpPlayerSettings getPlayerSettings(BluetoothDevice device) {
if (DBG) Log.d(TAG, "getPlayerSettings");
BluetoothAvrcpPlayerSettings settings = null;
- if (mService != null && isEnabled()) {
+ final IBluetoothAvrcpController service = mService;
+ if (service != null && isEnabled()) {
try {
- settings = mService.getPlayerSettings(device);
+ settings = service.getPlayerSettings(device);
} catch (RemoteException e) {
Log.e(TAG, "Error talking to BT service in getMetadata() " + e);
return null;
@@ -252,15 +253,16 @@
*/
public boolean setPlayerApplicationSetting(BluetoothAvrcpPlayerSettings plAppSetting) {
if (DBG) Log.d(TAG, "setPlayerApplicationSetting");
- if (mService != null && isEnabled()) {
+ final IBluetoothAvrcpController service = mService;
+ if (service != null && isEnabled()) {
try {
- return mService.setPlayerApplicationSetting(plAppSetting);
+ return service.setPlayerApplicationSetting(plAppSetting);
} catch (RemoteException e) {
Log.e(TAG, "Error talking to BT service in setPlayerApplicationSetting() " + e);
return false;
}
}
- if (mService == null) Log.w(TAG, "Proxy not attached to service");
+ if (service == null) Log.w(TAG, "Proxy not attached to service");
return false;
}
@@ -269,24 +271,25 @@
* possible keycode values: next_grp, previous_grp defined above
*/
public void sendGroupNavigationCmd(BluetoothDevice device, int keyCode, int keyState) {
- Log.d(TAG, "sendGroupNavigationCmd dev = " + device + " key " + keyCode + " State = " + keyState);
- if (mService != null && isEnabled()) {
+ Log.d(TAG, "sendGroupNavigationCmd dev = " + device + " key " + keyCode + " State = "
+ + keyState);
+ final IBluetoothAvrcpController service = mService;
+ if (service != null && isEnabled()) {
try {
- mService.sendGroupNavigationCmd(device, keyCode, keyState);
+ service.sendGroupNavigationCmd(device, keyCode, keyState);
return;
} catch (RemoteException e) {
Log.e(TAG, "Error talking to BT service in sendGroupNavigationCmd()", e);
return;
}
}
- if (mService == null) Log.w(TAG, "Proxy not attached to service");
+ if (service == null) Log.w(TAG, "Proxy not attached to service");
}
private final ServiceConnection mConnection = new ServiceConnection() {
public void onServiceConnected(ComponentName className, IBinder service) {
if (DBG) Log.d(TAG, "Proxy object connected");
mService = IBluetoothAvrcpController.Stub.asInterface(Binder.allowBlocking(service));
-
if (mServiceListener != null) {
mServiceListener.onServiceConnected(BluetoothProfile.AVRCP_CONTROLLER,
BluetoothAvrcpController.this);
@@ -302,15 +305,11 @@
};
private boolean isEnabled() {
- if (mAdapter.getState() == BluetoothAdapter.STATE_ON) return true;
- return false;
+ return mAdapter.getState() == BluetoothAdapter.STATE_ON;
}
- private boolean isValidDevice(BluetoothDevice device) {
- if (device == null) return false;
-
- if (BluetoothAdapter.checkBluetoothAddress(device.getAddress())) return true;
- return false;
+ private static boolean isValidDevice(BluetoothDevice device) {
+ return device != null && BluetoothAdapter.checkBluetoothAddress(device.getAddress());
}
private static void log(String msg) {
diff --git a/core/java/android/bluetooth/BluetoothDevice.java b/core/java/android/bluetooth/BluetoothDevice.java
index a206b53..98cd319 100644
--- a/core/java/android/bluetooth/BluetoothDevice.java
+++ b/core/java/android/bluetooth/BluetoothDevice.java
@@ -23,10 +23,9 @@
import android.annotation.SystemApi;
import android.content.Context;
import android.os.Handler;
-import android.os.Looper;
import android.os.Parcel;
-import android.os.Parcelable;
import android.os.ParcelUuid;
+import android.os.Parcelable;
import android.os.Process;
import android.os.RemoteException;
import android.util.Log;
@@ -683,7 +682,7 @@
* getService() called.
* TODO: Unify implementation of sService amongst BluetoothFoo API's
*/
- private static IBluetooth sService;
+ private static volatile IBluetooth sService;
private final String mAddress;
@@ -803,13 +802,16 @@
*/
@RequiresPermission(Manifest.permission.BLUETOOTH)
public String getName() {
- if (sService == null) {
+ final IBluetooth service = sService;
+ if (service == null) {
Log.e(TAG, "BT not enabled. Cannot get Remote Device name");
return null;
}
try {
- return sService.getRemoteName(this);
- } catch (RemoteException e) {Log.e(TAG, "", e);}
+ return service.getRemoteName(this);
+ } catch (RemoteException e) {
+ Log.e(TAG, "", e);
+ }
return null;
}
@@ -822,13 +824,16 @@
*/
@RequiresPermission(Manifest.permission.BLUETOOTH)
public int getType() {
- if (sService == null) {
+ final IBluetooth service = sService;
+ if (service == null) {
Log.e(TAG, "BT not enabled. Cannot get Remote Device type");
return DEVICE_TYPE_UNKNOWN;
}
try {
- return sService.getRemoteType(this);
- } catch (RemoteException e) {Log.e(TAG, "", e);}
+ return service.getRemoteType(this);
+ } catch (RemoteException e) {
+ Log.e(TAG, "", e);
+ }
return DEVICE_TYPE_UNKNOWN;
}
@@ -840,13 +845,16 @@
* @hide
*/
public String getAlias() {
- if (sService == null) {
+ final IBluetooth service = sService;
+ if (service == null) {
Log.e(TAG, "BT not enabled. Cannot get Remote Device Alias");
return null;
}
try {
- return sService.getRemoteAlias(this);
- } catch (RemoteException e) {Log.e(TAG, "", e);}
+ return service.getRemoteAlias(this);
+ } catch (RemoteException e) {
+ Log.e(TAG, "", e);
+ }
return null;
}
@@ -861,13 +869,16 @@
* @hide
*/
public boolean setAlias(String alias) {
- if (sService == null) {
+ final IBluetooth service = sService;
+ if (service == null) {
Log.e(TAG, "BT not enabled. Cannot set Remote Device name");
return false;
}
try {
- return sService.setRemoteAlias(this, alias);
- } catch (RemoteException e) {Log.e(TAG, "", e);}
+ return service.setRemoteAlias(this, alias);
+ } catch (RemoteException e) {
+ Log.e(TAG, "", e);
+ }
return false;
}
@@ -899,13 +910,16 @@
*/
@RequiresPermission(Manifest.permission.BLUETOOTH)
public int getBatteryLevel() {
- if (sService == null) {
+ final IBluetooth service = sService;
+ if (service == null) {
Log.e(TAG, "Bluetooth disabled. Cannot get remote device battery level");
return BATTERY_LEVEL_UNKNOWN;
}
try {
- return sService.getBatteryLevel(this);
- } catch (RemoteException e) {Log.e(TAG, "", e);}
+ return service.getBatteryLevel(this);
+ } catch (RemoteException e) {
+ Log.e(TAG, "", e);
+ }
return BATTERY_LEVEL_UNKNOWN;
}
@@ -921,16 +935,19 @@
*/
@RequiresPermission(Manifest.permission.BLUETOOTH_ADMIN)
public boolean createBond() {
- if (sService == null) {
+ final IBluetooth service = sService;
+ if (service == null) {
Log.e(TAG, "BT not enabled. Cannot create bond to Remote Device");
return false;
}
try {
- Log.i(TAG, "createBond() for device " + getAddress() +
- " called by pid: " + Process.myPid() +
- " tid: " + Process.myTid());
- return sService.createBond(this, TRANSPORT_AUTO);
- } catch (RemoteException e) {Log.e(TAG, "", e);}
+ Log.i(TAG, "createBond() for device " + getAddress()
+ + " called by pid: " + Process.myPid()
+ + " tid: " + Process.myTid());
+ return service.createBond(this, TRANSPORT_AUTO);
+ } catch (RemoteException e) {
+ Log.e(TAG, "", e);
+ }
return false;
}
@@ -951,7 +968,8 @@
* @hide
*/
public boolean createBond(int transport) {
- if (sService == null) {
+ final IBluetooth service = sService;
+ if (service == null) {
Log.e(TAG, "BT not enabled. Cannot create bond to Remote Device");
return false;
}
@@ -960,11 +978,13 @@
throw new IllegalArgumentException(transport + " is not a valid Bluetooth transport");
}
try {
- Log.i(TAG, "createBond() for device " + getAddress() +
- " called by pid: " + Process.myPid() +
- " tid: " + Process.myTid());
- return sService.createBond(this, transport);
- } catch (RemoteException e) {Log.e(TAG, "", e);}
+ Log.i(TAG, "createBond() for device " + getAddress()
+ + " called by pid: " + Process.myPid()
+ + " tid: " + Process.myTid());
+ return service.createBond(this, transport);
+ } catch (RemoteException e) {
+ Log.e(TAG, "", e);
+ }
return false;
}
@@ -988,17 +1008,31 @@
* @hide
*/
public boolean createBondOutOfBand(int transport, OobData oobData) {
+ final IBluetooth service = sService;
+ if (service == null) {
+ Log.w(TAG, "BT not enabled, createBondOutOfBand failed");
+ return false;
+ }
try {
- return sService.createBondOutOfBand(this, transport, oobData);
- } catch (RemoteException e) {Log.e(TAG, "", e);}
+ return service.createBondOutOfBand(this, transport, oobData);
+ } catch (RemoteException e) {
+ Log.e(TAG, "", e);
+ }
return false;
}
/** @hide */
public boolean isBondingInitiatedLocally() {
+ final IBluetooth service = sService;
+ if (service == null) {
+ Log.w(TAG, "BT not enabled, isBondingInitiatedLocally failed");
+ return false;
+ }
try {
- return sService.isBondingInitiatedLocally(this);
- } catch (RemoteException e) {Log.e(TAG, "", e);}
+ return service.isBondingInitiatedLocally(this);
+ } catch (RemoteException e) {
+ Log.e(TAG, "", e);
+ }
return false;
}
@@ -1032,16 +1066,19 @@
* @hide
*/
public boolean cancelBondProcess() {
- if (sService == null) {
+ final IBluetooth service = sService;
+ if (service == null) {
Log.e(TAG, "BT not enabled. Cannot cancel Remote Device bond");
return false;
}
try {
- Log.i(TAG, "cancelBondProcess() for device " + getAddress() +
- " called by pid: " + Process.myPid() +
- " tid: " + Process.myTid());
- return sService.cancelBondProcess(this);
- } catch (RemoteException e) {Log.e(TAG, "", e);}
+ Log.i(TAG, "cancelBondProcess() for device " + getAddress()
+ + " called by pid: " + Process.myPid()
+ + " tid: " + Process.myTid());
+ return service.cancelBondProcess(this);
+ } catch (RemoteException e) {
+ Log.e(TAG, "", e);
+ }
return false;
}
@@ -1056,16 +1093,19 @@
* @hide
*/
public boolean removeBond() {
- if (sService == null) {
+ final IBluetooth service = sService;
+ if (service == null) {
Log.e(TAG, "BT not enabled. Cannot remove Remote Device bond");
return false;
}
try {
- Log.i(TAG, "removeBond() for device " + getAddress() +
- " called by pid: " + Process.myPid() +
- " tid: " + Process.myTid());
- return sService.removeBond(this);
- } catch (RemoteException e) {Log.e(TAG, "", e);}
+ Log.i(TAG, "removeBond() for device " + getAddress()
+ + " called by pid: " + Process.myPid()
+ + " tid: " + Process.myTid());
+ return service.removeBond(this);
+ } catch (RemoteException e) {
+ Log.e(TAG, "", e);
+ }
return false;
}
@@ -1080,18 +1120,15 @@
*/
@RequiresPermission(Manifest.permission.BLUETOOTH)
public int getBondState() {
- if (sService == null) {
+ final IBluetooth service = sService;
+ if (service == null) {
Log.e(TAG, "BT not enabled. Cannot get bond state");
return BOND_NONE;
}
try {
- return sService.getBondState(this);
- } catch (RemoteException e) {Log.e(TAG, "", e);}
- catch (NullPointerException npe) {
- // Handle case where bluetooth service proxy
- // is already null.
- Log.e(TAG, "NullPointerException for getBondState() of device ("+
- getAddress()+")", npe);
+ return service.getBondState(this);
+ } catch (RemoteException e) {
+ Log.e(TAG, "", e);
}
return BOND_NONE;
}
@@ -1105,12 +1142,13 @@
*/
@SystemApi
public boolean isConnected() {
- if (sService == null) {
+ final IBluetooth service = sService;
+ if (service == null) {
// BT is not enabled, we cannot be connected.
return false;
}
try {
- return sService.getConnectionState(this) != CONNECTION_STATE_DISCONNECTED;
+ return service.getConnectionState(this) != CONNECTION_STATE_DISCONNECTED;
} catch (RemoteException e) {
Log.e(TAG, "", e);
return false;
@@ -1127,12 +1165,13 @@
*/
@SystemApi
public boolean isEncrypted() {
- if (sService == null) {
+ final IBluetooth service = sService;
+ if (service == null) {
// BT is not enabled, we cannot be connected.
return false;
}
try {
- return sService.getConnectionState(this) > CONNECTION_STATE_CONNECTED;
+ return service.getConnectionState(this) > CONNECTION_STATE_CONNECTED;
} catch (RemoteException e) {
Log.e(TAG, "", e);
return false;
@@ -1146,12 +1185,13 @@
*/
@RequiresPermission(Manifest.permission.BLUETOOTH)
public BluetoothClass getBluetoothClass() {
- if (sService == null) {
+ final IBluetooth service = sService;
+ if (service == null) {
Log.e(TAG, "BT not enabled. Cannot get Bluetooth Class");
return null;
}
try {
- int classInt = sService.getRemoteClass(this);
+ int classInt = service.getRemoteClass(this);
if (classInt == BluetoothClass.ERROR) return null;
return new BluetoothClass(classInt);
} catch (RemoteException e) {Log.e(TAG, "", e);}
@@ -1170,75 +1210,82 @@
* or null on error
*/
@RequiresPermission(Manifest.permission.BLUETOOTH)
- public ParcelUuid[] getUuids() {
- if (sService == null || isBluetoothEnabled() == false) {
+ public ParcelUuid[] getUuids() {
+ final IBluetooth service = sService;
+ if (service == null || !isBluetoothEnabled()) {
Log.e(TAG, "BT not enabled. Cannot get remote device Uuids");
return null;
}
try {
- return sService.getRemoteUuids(this);
- } catch (RemoteException e) {Log.e(TAG, "", e);}
+ return service.getRemoteUuids(this);
+ } catch (RemoteException e) {
+ Log.e(TAG, "", e);
+ }
return null;
}
- /**
- * Perform a service discovery on the remote device to get the UUIDs supported.
- *
- * <p>This API is asynchronous and {@link #ACTION_UUID} intent is sent,
- * with the UUIDs supported by the remote end. If there is an error
- * in getting the SDP records or if the process takes a long time,
- * {@link #ACTION_UUID} intent is sent with the UUIDs that is currently
- * present in the cache. Clients should use the {@link #getUuids} to get UUIDs
- * if service discovery is not to be performed.
- *
- * @return False if the sanity check fails, True if the process
- * of initiating an ACL connection to the remote device
- * was started.
- */
- @RequiresPermission(Manifest.permission.BLUETOOTH)
- public boolean fetchUuidsWithSdp() {
- IBluetooth service = sService;
- if (service == null || isBluetoothEnabled() == false) {
+ /**
+ * Perform a service discovery on the remote device to get the UUIDs supported.
+ *
+ * <p>This API is asynchronous and {@link #ACTION_UUID} intent is sent,
+ * with the UUIDs supported by the remote end. If there is an error
+ * in getting the SDP records or if the process takes a long time,
+ * {@link #ACTION_UUID} intent is sent with the UUIDs that is currently
+ * present in the cache. Clients should use the {@link #getUuids} to get UUIDs
+ * if service discovery is not to be performed.
+ *
+ * @return False if the sanity check fails, True if the process of initiating an ACL connection
+ * to the remote device was started.
+ */
+ @RequiresPermission(Manifest.permission.BLUETOOTH)
+ public boolean fetchUuidsWithSdp() {
+ final IBluetooth service = sService;
+ if (service == null || !isBluetoothEnabled()) {
Log.e(TAG, "BT not enabled. Cannot fetchUuidsWithSdp");
return false;
}
try {
return service.fetchRemoteUuids(this);
- } catch (RemoteException e) {Log.e(TAG, "", e);}
- return false;
+ } catch (RemoteException e) {
+ Log.e(TAG, "", e);
+ }
+ return false;
}
- /**
- * Perform a service discovery on the remote device to get the SDP records associated
- * with the specified UUID.
- *
- * <p>This API is asynchronous and {@link #ACTION_SDP_RECORD} intent is sent,
- * with the SDP records found on the remote end. If there is an error
- * in getting the SDP records or if the process takes a long time,
- * {@link #ACTION_SDP_RECORD} intent is sent with an status value in
- * {@link #EXTRA_SDP_SEARCH_STATUS} different from 0.
- * Detailed status error codes can be found by members of the Bluetooth package in
- * the AbstractionLayer class.
- * <p>Requires {@link android.Manifest.permission#BLUETOOTH}.
- * The SDP record data will be stored in the intent as {@link #EXTRA_SDP_RECORD}.
- * The object type will match one of the SdpXxxRecord types, depending on the UUID searched
- * for.
- *
- * @return False if the sanity check fails, True if the process
- * of initiating an ACL connection to the remote device
- * was started.
- */
- /** @hide */
- public boolean sdpSearch(ParcelUuid uuid) {
- if (sService == null) {
- Log.e(TAG, "BT not enabled. Cannot query remote device sdp records");
- return false;
- }
- try {
- return sService.sdpSearch(this,uuid);
- } catch (RemoteException e) {Log.e(TAG, "", e);}
- return false;
- }
+ /**
+ * Perform a service discovery on the remote device to get the SDP records associated
+ * with the specified UUID.
+ *
+ * <p>This API is asynchronous and {@link #ACTION_SDP_RECORD} intent is sent,
+ * with the SDP records found on the remote end. If there is an error
+ * in getting the SDP records or if the process takes a long time,
+ * {@link #ACTION_SDP_RECORD} intent is sent with an status value in
+ * {@link #EXTRA_SDP_SEARCH_STATUS} different from 0.
+ * Detailed status error codes can be found by members of the Bluetooth package in
+ * the AbstractionLayer class.
+ * <p>Requires {@link android.Manifest.permission#BLUETOOTH}.
+ * The SDP record data will be stored in the intent as {@link #EXTRA_SDP_RECORD}.
+ * The object type will match one of the SdpXxxRecord types, depending on the UUID searched
+ * for.
+ *
+ * @return False if the sanity check fails, True if the process
+ * of initiating an ACL connection to the remote device
+ * was started.
+ */
+ /** @hide */
+ public boolean sdpSearch(ParcelUuid uuid) {
+ final IBluetooth service = sService;
+ if (service == null) {
+ Log.e(TAG, "BT not enabled. Cannot query remote device sdp records");
+ return false;
+ }
+ try {
+ return service.sdpSearch(this, uuid);
+ } catch (RemoteException e) {
+ Log.e(TAG, "", e);
+ }
+ return false;
+ }
/**
* Set the pin during pairing when the pairing method is {@link #PAIRING_VARIANT_PIN}
@@ -1248,13 +1295,16 @@
* false for error
*/
public boolean setPin(byte[] pin) {
- if (sService == null) {
+ final IBluetooth service = sService;
+ if (service == null) {
Log.e(TAG, "BT not enabled. Cannot set Remote Device pin");
return false;
}
try {
- return sService.setPin(this, true, pin.length, pin);
- } catch (RemoteException e) {Log.e(TAG, "", e);}
+ return service.setPin(this, true, pin.length, pin);
+ } catch (RemoteException e) {
+ Log.e(TAG, "", e);
+ }
return false;
}
@@ -1276,13 +1326,16 @@
*/
@RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED)
public boolean setPairingConfirmation(boolean confirm) {
- if (sService == null) {
+ final IBluetooth service = sService;
+ if (service == null) {
Log.e(TAG, "BT not enabled. Cannot set pairing confirmation");
return false;
}
try {
- return sService.setPairingConfirmation(this, confirm);
- } catch (RemoteException e) {Log.e(TAG, "", e);}
+ return service.setPairingConfirmation(this, confirm);
+ } catch (RemoteException e) {
+ Log.e(TAG, "", e);
+ }
return false;
}
@@ -1298,13 +1351,16 @@
/** @hide */
public boolean cancelPairingUserInput() {
- if (sService == null) {
+ final IBluetooth service = sService;
+ if (service == null) {
Log.e(TAG, "BT not enabled. Cannot create pairing user input");
return false;
}
try {
- return sService.cancelBondProcess(this);
- } catch (RemoteException e) {Log.e(TAG, "", e);}
+ return service.cancelBondProcess(this);
+ } catch (RemoteException e) {
+ Log.e(TAG, "", e);
+ }
return false;
}
@@ -1334,11 +1390,12 @@
* @hide
*/
public int getPhonebookAccessPermission() {
- if (sService == null) {
+ final IBluetooth service = sService;
+ if (service == null) {
return ACCESS_UNKNOWN;
}
try {
- return sService.getPhonebookAccessPermission(this);
+ return service.getPhonebookAccessPermission(this);
} catch (RemoteException e) {
Log.e(TAG, "", e);
}
@@ -1354,11 +1411,12 @@
* @hide
*/
public boolean setPhonebookAccessPermission(int value) {
- if (sService == null) {
+ final IBluetooth service = sService;
+ if (service == null) {
return false;
}
try {
- return sService.setPhonebookAccessPermission(this, value);
+ return service.setPhonebookAccessPermission(this, value);
} catch (RemoteException e) {
Log.e(TAG, "", e);
}
@@ -1372,11 +1430,12 @@
* @hide
*/
public int getMessageAccessPermission() {
- if (sService == null) {
+ final IBluetooth service = sService;
+ if (service == null) {
return ACCESS_UNKNOWN;
}
try {
- return sService.getMessageAccessPermission(this);
+ return service.getMessageAccessPermission(this);
} catch (RemoteException e) {
Log.e(TAG, "", e);
}
@@ -1392,11 +1451,12 @@
* @hide
*/
public boolean setMessageAccessPermission(int value) {
- if (sService == null) {
+ final IBluetooth service = sService;
+ if (service == null) {
return false;
}
try {
- return sService.setMessageAccessPermission(this, value);
+ return service.setMessageAccessPermission(this, value);
} catch (RemoteException e) {
Log.e(TAG, "", e);
}
@@ -1410,11 +1470,12 @@
* @hide
*/
public int getSimAccessPermission() {
- if (sService == null) {
+ final IBluetooth service = sService;
+ if (service == null) {
return ACCESS_UNKNOWN;
}
try {
- return sService.getSimAccessPermission(this);
+ return service.getSimAccessPermission(this);
} catch (RemoteException e) {
Log.e(TAG, "", e);
}
@@ -1430,11 +1491,12 @@
* @hide
*/
public boolean setSimAccessPermission(int value) {
- if (sService == null) {
+ final IBluetooth service = sService;
+ if (service == null) {
return false;
}
try {
- return sService.setSimAccessPermission(this, value);
+ return service.setSimAccessPermission(this, value);
} catch (RemoteException e) {
Log.e(TAG, "", e);
}
diff --git a/core/java/android/bluetooth/BluetoothHeadset.java b/core/java/android/bluetooth/BluetoothHeadset.java
index c84643f..500cba3 100644
--- a/core/java/android/bluetooth/BluetoothHeadset.java
+++ b/core/java/android/bluetooth/BluetoothHeadset.java
@@ -298,7 +298,7 @@
private Context mContext;
private ServiceListener mServiceListener;
- private IBluetoothHeadset mService;
+ private volatile IBluetoothHeadset mService;
private BluetoothAdapter mAdapter;
final private IBluetoothStateChangeCallback mBluetoothStateChangeCallback =
@@ -411,16 +411,16 @@
*/
public boolean connect(BluetoothDevice device) {
if (DBG) log("connect(" + device + ")");
- if (mService != null && isEnabled() &&
- isValidDevice(device)) {
+ final IBluetoothHeadset service = mService;
+ if (service != null && isEnabled() && isValidDevice(device)) {
try {
- return mService.connect(device);
+ return service.connect(device);
} catch (RemoteException e) {
Log.e(TAG, Log.getStackTraceString(new Throwable()));
return false;
}
}
- if (mService == null) Log.w(TAG, "Proxy not attached to service");
+ if (service == null) Log.w(TAG, "Proxy not attached to service");
return false;
}
@@ -452,16 +452,16 @@
*/
public boolean disconnect(BluetoothDevice device) {
if (DBG) log("disconnect(" + device + ")");
- if (mService != null && isEnabled() &&
- isValidDevice(device)) {
+ final IBluetoothHeadset service = mService;
+ if (service != null && isEnabled() && isValidDevice(device)) {
try {
- return mService.disconnect(device);
+ return service.disconnect(device);
} catch (RemoteException e) {
Log.e(TAG, Log.getStackTraceString(new Throwable()));
return false;
}
}
- if (mService == null) Log.w(TAG, "Proxy not attached to service");
+ if (service == null) Log.w(TAG, "Proxy not attached to service");
return false;
}
@@ -470,15 +470,16 @@
*/
public List<BluetoothDevice> getConnectedDevices() {
if (VDBG) log("getConnectedDevices()");
- if (mService != null && isEnabled()) {
+ final IBluetoothHeadset service = mService;
+ if (service != null && isEnabled()) {
try {
- return mService.getConnectedDevices();
+ return service.getConnectedDevices();
} catch (RemoteException e) {
Log.e(TAG, Log.getStackTraceString(new Throwable()));
return new ArrayList<BluetoothDevice>();
}
}
- if (mService == null) Log.w(TAG, "Proxy not attached to service");
+ if (service == null) Log.w(TAG, "Proxy not attached to service");
return new ArrayList<BluetoothDevice>();
}
@@ -487,15 +488,16 @@
*/
public List<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states) {
if (VDBG) log("getDevicesMatchingStates()");
- if (mService != null && isEnabled()) {
+ final IBluetoothHeadset service = mService;
+ if (service != null && isEnabled()) {
try {
- return mService.getDevicesMatchingConnectionStates(states);
+ return service.getDevicesMatchingConnectionStates(states);
} catch (RemoteException e) {
Log.e(TAG, Log.getStackTraceString(new Throwable()));
return new ArrayList<BluetoothDevice>();
}
}
- if (mService == null) Log.w(TAG, "Proxy not attached to service");
+ if (service == null) Log.w(TAG, "Proxy not attached to service");
return new ArrayList<BluetoothDevice>();
}
@@ -504,16 +506,16 @@
*/
public int getConnectionState(BluetoothDevice device) {
if (VDBG) log("getConnectionState(" + device + ")");
- if (mService != null && isEnabled() &&
- isValidDevice(device)) {
+ final IBluetoothHeadset service = mService;
+ if (service != null && isEnabled() && isValidDevice(device)) {
try {
- return mService.getConnectionState(device);
+ return service.getConnectionState(device);
} catch (RemoteException e) {
Log.e(TAG, Log.getStackTraceString(new Throwable()));
return BluetoothProfile.STATE_DISCONNECTED;
}
}
- if (mService == null) Log.w(TAG, "Proxy not attached to service");
+ if (service == null) Log.w(TAG, "Proxy not attached to service");
return BluetoothProfile.STATE_DISCONNECTED;
}
@@ -534,20 +536,20 @@
*/
public boolean setPriority(BluetoothDevice device, int priority) {
if (DBG) log("setPriority(" + device + ", " + priority + ")");
- if (mService != null && isEnabled() &&
- isValidDevice(device)) {
- if (priority != BluetoothProfile.PRIORITY_OFF &&
- priority != BluetoothProfile.PRIORITY_ON) {
- return false;
+ final IBluetoothHeadset service = mService;
+ if (service != null && isEnabled() && isValidDevice(device)) {
+ if (priority != BluetoothProfile.PRIORITY_OFF
+ && priority != BluetoothProfile.PRIORITY_ON) {
+ return false;
}
try {
- return mService.setPriority(device, priority);
+ return service.setPriority(device, priority);
} catch (RemoteException e) {
Log.e(TAG, Log.getStackTraceString(new Throwable()));
return false;
}
}
- if (mService == null) Log.w(TAG, "Proxy not attached to service");
+ if (service == null) Log.w(TAG, "Proxy not attached to service");
return false;
}
@@ -566,16 +568,16 @@
*/
public int getPriority(BluetoothDevice device) {
if (VDBG) log("getPriority(" + device + ")");
- if (mService != null && isEnabled() &&
- isValidDevice(device)) {
+ final IBluetoothHeadset service = mService;
+ if (service != null && isEnabled() && isValidDevice(device)) {
try {
- return mService.getPriority(device);
+ return service.getPriority(device);
} catch (RemoteException e) {
Log.e(TAG, Log.getStackTraceString(new Throwable()));
return PRIORITY_OFF;
}
}
- if (mService == null) Log.w(TAG, "Proxy not attached to service");
+ if (service == null) Log.w(TAG, "Proxy not attached to service");
return PRIORITY_OFF;
}
@@ -602,15 +604,15 @@
*/
public boolean startVoiceRecognition(BluetoothDevice device) {
if (DBG) log("startVoiceRecognition()");
- if (mService != null && isEnabled() &&
- isValidDevice(device)) {
+ final IBluetoothHeadset service = mService;
+ if (service != null && isEnabled() && isValidDevice(device)) {
try {
- return mService.startVoiceRecognition(device);
+ return service.startVoiceRecognition(device);
} catch (RemoteException e) {
Log.e(TAG, Log.getStackTraceString(new Throwable()));
}
}
- if (mService == null) Log.w(TAG, "Proxy not attached to service");
+ if (service == null) Log.w(TAG, "Proxy not attached to service");
return false;
}
@@ -626,15 +628,15 @@
*/
public boolean stopVoiceRecognition(BluetoothDevice device) {
if (DBG) log("stopVoiceRecognition()");
- if (mService != null && isEnabled() &&
- isValidDevice(device)) {
+ final IBluetoothHeadset service = mService;
+ if (service != null && isEnabled() && isValidDevice(device)) {
try {
- return mService.stopVoiceRecognition(device);
+ return service.stopVoiceRecognition(device);
} catch (RemoteException e) {
Log.e(TAG, Log.getStackTraceString(new Throwable()));
}
}
- if (mService == null) Log.w(TAG, "Proxy not attached to service");
+ if (service == null) Log.w(TAG, "Proxy not attached to service");
return false;
}
@@ -649,15 +651,15 @@
*/
public boolean isAudioConnected(BluetoothDevice device) {
if (VDBG) log("isAudioConnected()");
- if (mService != null && isEnabled() &&
- isValidDevice(device)) {
+ final IBluetoothHeadset service = mService;
+ if (service != null && isEnabled() && isValidDevice(device)) {
try {
- return mService.isAudioConnected(device);
+ return service.isAudioConnected(device);
} catch (RemoteException e) {
Log.e(TAG, Log.getStackTraceString(new Throwable()));
}
}
- if (mService == null) Log.w(TAG, "Proxy not attached to service");
+ if (service == null) Log.w(TAG, "Proxy not attached to service");
return false;
}
@@ -677,15 +679,15 @@
*/
public int getBatteryUsageHint(BluetoothDevice device) {
if (VDBG) log("getBatteryUsageHint()");
- if (mService != null && isEnabled() &&
- isValidDevice(device)) {
+ final IBluetoothHeadset service = mService;
+ if (service != null && isEnabled() && isValidDevice(device)) {
try {
- return mService.getBatteryUsageHint(device);
+ return service.getBatteryUsageHint(device);
} catch (RemoteException e) {
Log.e(TAG, Log.getStackTraceString(new Throwable()));
}
}
- if (mService == null) Log.w(TAG, "Proxy not attached to service");
+ if (service == null) Log.w(TAG, "Proxy not attached to service");
return -1;
}
@@ -708,10 +710,13 @@
*/
public boolean acceptIncomingConnect(BluetoothDevice device) {
if (DBG) log("acceptIncomingConnect");
- if (mService != null && isEnabled()) {
+ final IBluetoothHeadset service = mService;
+ if (service != null && isEnabled()) {
try {
- return mService.acceptIncomingConnect(device);
- } catch (RemoteException e) {Log.e(TAG, e.toString());}
+ return service.acceptIncomingConnect(device);
+ } catch (RemoteException e) {
+ Log.e(TAG, e.toString());
+ }
} else {
Log.w(TAG, "Proxy not attached to service");
if (DBG) Log.d(TAG, Log.getStackTraceString(new Throwable()));
@@ -725,10 +730,13 @@
*/
public boolean rejectIncomingConnect(BluetoothDevice device) {
if (DBG) log("rejectIncomingConnect");
- if (mService != null) {
+ final IBluetoothHeadset service = mService;
+ if (service != null) {
try {
- return mService.rejectIncomingConnect(device);
- } catch (RemoteException e) {Log.e(TAG, e.toString());}
+ return service.rejectIncomingConnect(device);
+ } catch (RemoteException e) {
+ Log.e(TAG, e.toString());
+ }
} else {
Log.w(TAG, "Proxy not attached to service");
if (DBG) Log.d(TAG, Log.getStackTraceString(new Throwable()));
@@ -744,10 +752,13 @@
*/
public int getAudioState(BluetoothDevice device) {
if (VDBG) log("getAudioState");
- if (mService != null && !isDisabled()) {
+ final IBluetoothHeadset service = mService;
+ if (service != null && !isDisabled()) {
try {
- return mService.getAudioState(device);
- } catch (RemoteException e) {Log.e(TAG, e.toString());}
+ return service.getAudioState(device);
+ } catch (RemoteException e) {
+ Log.e(TAG, e.toString());
+ }
} else {
Log.w(TAG, "Proxy not attached to service");
if (DBG) Log.d(TAG, Log.getStackTraceString(new Throwable()));
@@ -768,10 +779,13 @@
*/
public void setAudioRouteAllowed(boolean allowed) {
if (VDBG) log("setAudioRouteAllowed");
- if (mService != null && isEnabled()) {
+ final IBluetoothHeadset service = mService;
+ if (service != null && isEnabled()) {
try {
- mService.setAudioRouteAllowed(allowed);
- } catch (RemoteException e) {Log.e(TAG, e.toString());}
+ service.setAudioRouteAllowed(allowed);
+ } catch (RemoteException e) {
+ Log.e(TAG, e.toString());
+ }
} else {
Log.w(TAG, "Proxy not attached to service");
if (DBG) Log.d(TAG, Log.getStackTraceString(new Throwable()));
@@ -786,10 +800,13 @@
*/
public boolean getAudioRouteAllowed() {
if (VDBG) log("getAudioRouteAllowed");
- if (mService != null && isEnabled()) {
+ final IBluetoothHeadset service = mService;
+ if (service != null && isEnabled()) {
try {
- return mService.getAudioRouteAllowed();
- } catch (RemoteException e) {Log.e(TAG, e.toString());}
+ return service.getAudioRouteAllowed();
+ } catch (RemoteException e) {
+ Log.e(TAG, e.toString());
+ }
} else {
Log.w(TAG, "Proxy not attached to service");
if (DBG) Log.d(TAG, Log.getStackTraceString(new Throwable()));
@@ -807,9 +824,10 @@
*/
public void setForceScoAudio(boolean forced) {
if (VDBG) log("setForceScoAudio " + String.valueOf(forced));
- if (mService != null && isEnabled()) {
+ final IBluetoothHeadset service = mService;
+ if (service != null && isEnabled()) {
try {
- mService.setForceScoAudio(forced);
+ service.setForceScoAudio(forced);
} catch (RemoteException e) {
Log.e(TAG, e.toString());
}
@@ -830,14 +848,15 @@
*/
public boolean isAudioOn() {
if (VDBG) log("isAudioOn()");
- if (mService != null && isEnabled()) {
+ final IBluetoothHeadset service = mService;
+ if (service != null && isEnabled()) {
try {
- return mService.isAudioOn();
+ return service.isAudioOn();
} catch (RemoteException e) {
Log.e(TAG, Log.getStackTraceString(new Throwable()));
}
}
- if (mService == null) Log.w(TAG, "Proxy not attached to service");
+ if (service == null) Log.w(TAG, "Proxy not attached to service");
return false;
}
@@ -852,9 +871,10 @@
* @hide
*/
public boolean connectAudio() {
- if (mService != null && isEnabled()) {
+ final IBluetoothHeadset service = mService;
+ if (service != null && isEnabled()) {
try {
- return mService.connectAudio();
+ return service.connectAudio();
} catch (RemoteException e) {
Log.e(TAG, e.toString());
}
@@ -875,9 +895,10 @@
* @hide
*/
public boolean disconnectAudio() {
- if (mService != null && isEnabled()) {
+ final IBluetoothHeadset service = mService;
+ if (service != null && isEnabled()) {
try {
- return mService.disconnectAudio();
+ return service.disconnectAudio();
} catch (RemoteException e) {
Log.e(TAG, e.toString());
}
@@ -901,9 +922,10 @@
*/
public boolean startScoUsingVirtualVoiceCall(BluetoothDevice device) {
if (DBG) log("startScoUsingVirtualVoiceCall()");
- if (mService != null && isEnabled() && isValidDevice(device)) {
+ final IBluetoothHeadset service = mService;
+ if (service != null && isEnabled() && isValidDevice(device)) {
try {
- return mService.startScoUsingVirtualVoiceCall(device);
+ return service.startScoUsingVirtualVoiceCall(device);
} catch (RemoteException e) {
Log.e(TAG, e.toString());
}
@@ -924,9 +946,10 @@
*/
public boolean stopScoUsingVirtualVoiceCall(BluetoothDevice device) {
if (DBG) log("stopScoUsingVirtualVoiceCall()");
- if (mService != null && isEnabled() && isValidDevice(device)) {
+ final IBluetoothHeadset service = mService;
+ if (service != null && isEnabled() && isValidDevice(device)) {
try {
- return mService.stopScoUsingVirtualVoiceCall(device);
+ return service.stopScoUsingVirtualVoiceCall(device);
} catch (RemoteException e) {
Log.e(TAG, e.toString());
}
@@ -946,10 +969,11 @@
* @hide
*/
public void phoneStateChanged(int numActive, int numHeld, int callState, String number,
- int type) {
- if (mService != null && isEnabled()) {
+ int type) {
+ final IBluetoothHeadset service = mService;
+ if (service != null && isEnabled()) {
try {
- mService.phoneStateChanged(numActive, numHeld, callState, number, type);
+ service.phoneStateChanged(numActive, numHeld, callState, number, type);
} catch (RemoteException e) {
Log.e(TAG, e.toString());
}
@@ -965,10 +989,11 @@
* @hide
*/
public void clccResponse(int index, int direction, int status, int mode, boolean mpty,
- String number, int type) {
- if (mService != null && isEnabled()) {
+ String number, int type) {
+ final IBluetoothHeadset service = mService;
+ if (service != null && isEnabled()) {
try {
- mService.clccResponse(index, direction, status, mode, mpty, number, type);
+ service.clccResponse(index, direction, status, mode, mpty, number, type);
} catch (RemoteException e) {
Log.e(TAG, e.toString());
}
@@ -1004,15 +1029,15 @@
if (command == null) {
throw new IllegalArgumentException("command is null");
}
- if (mService != null && isEnabled() &&
- isValidDevice(device)) {
+ final IBluetoothHeadset service = mService;
+ if (service != null && isEnabled() && isValidDevice(device)) {
try {
- return mService.sendVendorSpecificResultCode(device, command, arg);
+ return service.sendVendorSpecificResultCode(device, command, arg);
} catch (RemoteException e) {
Log.e(TAG, Log.getStackTraceString(new Throwable()));
}
}
- if (mService == null) {
+ if (service == null) {
Log.w(TAG, "Proxy not attached to service");
}
return false;
@@ -1027,9 +1052,10 @@
* @hide
*/
public boolean enableWBS() {
- if (mService != null && isEnabled()) {
+ final IBluetoothHeadset service = mService;
+ if (service != null && isEnabled()) {
try {
- return mService.enableWBS();
+ return service.enableWBS();
} catch (RemoteException e) {
Log.e(TAG, e.toString());
}
@@ -1049,9 +1075,10 @@
* @hide
*/
public boolean disableWBS() {
- if (mService != null && isEnabled()) {
+ final IBluetoothHeadset service = mService;
+ if (service != null && isEnabled()) {
try {
- return mService.disableWBS();
+ return service.disableWBS();
} catch (RemoteException e) {
Log.e(TAG, e.toString());
}
@@ -1078,16 +1105,17 @@
* Send Headset the BIND response from AG to report change in the status of the
* HF indicators to the headset
*
- * @param ind_id Assigned Number of the indicator (defined by SIG)
- * @param ind_status
+ * @param indId Assigned Number of the indicator (defined by SIG)
+ * @param indStatus
* possible values- false-Indicator is disabled, no value changes shall be sent for this indicator
* true-Indicator is enabled, value changes may be sent for this indicator
* @hide
*/
- public void bindResponse(int ind_id, boolean ind_status) {
- if (mService != null && isEnabled()) {
+ public void bindResponse(int indId, boolean indStatus) {
+ final IBluetoothHeadset service = mService;
+ if (service != null && isEnabled()) {
try {
- mService.bindResponse(ind_id, ind_status);
+ service.bindResponse(indId, indStatus);
} catch (RemoteException e) {
Log.e(TAG, e.toString());
}
@@ -1116,20 +1144,15 @@
};
private boolean isEnabled() {
- if (mAdapter.getState() == BluetoothAdapter.STATE_ON) return true;
- return false;
+ return mAdapter.getState() == BluetoothAdapter.STATE_ON;
}
private boolean isDisabled() {
- if (mAdapter.getState() == BluetoothAdapter.STATE_OFF) return true;
- return false;
+ return mAdapter.getState() == BluetoothAdapter.STATE_OFF;
}
- private boolean isValidDevice(BluetoothDevice device) {
- if (device == null) return false;
-
- if (BluetoothAdapter.checkBluetoothAddress(device.getAddress())) return true;
- return false;
+ private static boolean isValidDevice(BluetoothDevice device) {
+ return device != null && BluetoothAdapter.checkBluetoothAddress(device.getAddress());
}
private static void log(String msg) {
diff --git a/core/java/android/bluetooth/BluetoothHeadsetClient.java b/core/java/android/bluetooth/BluetoothHeadsetClient.java
index 544b3b95..73a16de 100644
--- a/core/java/android/bluetooth/BluetoothHeadsetClient.java
+++ b/core/java/android/bluetooth/BluetoothHeadsetClient.java
@@ -28,7 +28,6 @@
import java.util.ArrayList;
import java.util.List;
-import java.util.UUID;
/**
* Public API to control Hands Free Profile (HFP role only).
@@ -77,8 +76,8 @@
* Intent sent whenever audio state changes.
*
* <p>It includes two mandatory extras:
- * {@link BluetoothProfile.EXTRA_STATE},
- * {@link BluetoothProfile.EXTRA_PREVIOUS_STATE},
+ * {@link BluetoothProfile#EXTRA_STATE},
+ * {@link BluetoothProfile#EXTRA_PREVIOUS_STATE},
* with possible values:
* {@link #STATE_AUDIO_CONNECTING},
* {@link #STATE_AUDIO_CONNECTED},
@@ -368,7 +367,7 @@
private Context mContext;
private ServiceListener mServiceListener;
- private IBluetoothHeadsetClient mService;
+ private volatile IBluetoothHeadsetClient mService;
private BluetoothAdapter mAdapter;
final private IBluetoothStateChangeCallback mBluetoothStateChangeCallback =
@@ -480,16 +479,16 @@
*/
public boolean connect(BluetoothDevice device) {
if (DBG) log("connect(" + device + ")");
- if (mService != null && isEnabled() &&
- isValidDevice(device)) {
+ final IBluetoothHeadsetClient service = mService;
+ if (service != null && isEnabled() && isValidDevice(device)) {
try {
- return mService.connect(device);
+ return service.connect(device);
} catch (RemoteException e) {
Log.e(TAG, Log.getStackTraceString(new Throwable()));
return false;
}
}
- if (mService == null) Log.w(TAG, "Proxy not attached to service");
+ if (service == null) Log.w(TAG, "Proxy not attached to service");
return false;
}
@@ -504,16 +503,16 @@
*/
public boolean disconnect(BluetoothDevice device) {
if (DBG) log("disconnect(" + device + ")");
- if (mService != null && isEnabled() &&
- isValidDevice(device)) {
+ final IBluetoothHeadsetClient service = mService;
+ if (service != null && isEnabled() && isValidDevice(device)) {
try {
- return mService.disconnect(device);
+ return service.disconnect(device);
} catch (RemoteException e) {
Log.e(TAG, Log.getStackTraceString(new Throwable()));
return false;
}
}
- if (mService == null) Log.w(TAG, "Proxy not attached to service");
+ if (service == null) Log.w(TAG, "Proxy not attached to service");
return false;
}
@@ -525,15 +524,16 @@
@Override
public List<BluetoothDevice> getConnectedDevices() {
if (VDBG) log("getConnectedDevices()");
- if (mService != null && isEnabled()) {
+ final IBluetoothHeadsetClient service = mService;
+ if (service != null && isEnabled()) {
try {
- return mService.getConnectedDevices();
+ return service.getConnectedDevices();
} catch (RemoteException e) {
Log.e(TAG, Log.getStackTraceString(new Throwable()));
return new ArrayList<BluetoothDevice>();
}
}
- if (mService == null) Log.w(TAG, "Proxy not attached to service");
+ if (service == null) Log.w(TAG, "Proxy not attached to service");
return new ArrayList<BluetoothDevice>();
}
@@ -548,15 +548,16 @@
@Override
public List<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states) {
if (VDBG) log("getDevicesMatchingStates()");
- if (mService != null && isEnabled()) {
+ final IBluetoothHeadsetClient service = mService;
+ if (service != null && isEnabled()) {
try {
- return mService.getDevicesMatchingConnectionStates(states);
+ return service.getDevicesMatchingConnectionStates(states);
} catch (RemoteException e) {
Log.e(TAG, Log.getStackTraceString(new Throwable()));
return new ArrayList<BluetoothDevice>();
}
}
- if (mService == null) Log.w(TAG, "Proxy not attached to service");
+ if (service == null) Log.w(TAG, "Proxy not attached to service");
return new ArrayList<BluetoothDevice>();
}
@@ -569,16 +570,16 @@
@Override
public int getConnectionState(BluetoothDevice device) {
if (VDBG) log("getConnectionState(" + device + ")");
- if (mService != null && isEnabled() &&
- isValidDevice(device)) {
+ final IBluetoothHeadsetClient service = mService;
+ if (service != null && isEnabled() && isValidDevice(device)) {
try {
- return mService.getConnectionState(device);
+ return service.getConnectionState(device);
} catch (RemoteException e) {
Log.e(TAG, Log.getStackTraceString(new Throwable()));
return BluetoothProfile.STATE_DISCONNECTED;
}
}
- if (mService == null) Log.w(TAG, "Proxy not attached to service");
+ if (service == null) Log.w(TAG, "Proxy not attached to service");
return BluetoothProfile.STATE_DISCONNECTED;
}
@@ -589,20 +590,20 @@
*/
public boolean setPriority(BluetoothDevice device, int priority) {
if (DBG) log("setPriority(" + device + ", " + priority + ")");
- if (mService != null && isEnabled() &&
- isValidDevice(device)) {
- if (priority != BluetoothProfile.PRIORITY_OFF &&
- priority != BluetoothProfile.PRIORITY_ON) {
- return false;
+ final IBluetoothHeadsetClient service = mService;
+ if (service != null && isEnabled() && isValidDevice(device)) {
+ if (priority != BluetoothProfile.PRIORITY_OFF
+ && priority != BluetoothProfile.PRIORITY_ON) {
+ return false;
}
try {
- return mService.setPriority(device, priority);
+ return service.setPriority(device, priority);
} catch (RemoteException e) {
Log.e(TAG, Log.getStackTraceString(new Throwable()));
return false;
}
}
- if (mService == null) Log.w(TAG, "Proxy not attached to service");
+ if (service == null) Log.w(TAG, "Proxy not attached to service");
return false;
}
@@ -611,16 +612,16 @@
*/
public int getPriority(BluetoothDevice device) {
if (VDBG) log("getPriority(" + device + ")");
- if (mService != null && isEnabled() &&
- isValidDevice(device)) {
+ final IBluetoothHeadsetClient service = mService;
+ if (service != null && isEnabled() && isValidDevice(device)) {
try {
- return mService.getPriority(device);
+ return service.getPriority(device);
} catch (RemoteException e) {
Log.e(TAG, Log.getStackTraceString(new Throwable()));
return PRIORITY_OFF;
}
}
- if (mService == null) Log.w(TAG, "Proxy not attached to service");
+ if (service == null) Log.w(TAG, "Proxy not attached to service");
return PRIORITY_OFF;
}
@@ -639,15 +640,15 @@
*/
public boolean startVoiceRecognition(BluetoothDevice device) {
if (DBG) log("startVoiceRecognition()");
- if (mService != null && isEnabled() &&
- isValidDevice(device)) {
+ final IBluetoothHeadsetClient service = mService;
+ if (service != null && isEnabled() && isValidDevice(device)) {
try {
- return mService.startVoiceRecognition(device);
+ return service.startVoiceRecognition(device);
} catch (RemoteException e) {
Log.e(TAG, Log.getStackTraceString(new Throwable()));
}
}
- if (mService == null) Log.w(TAG, "Proxy not attached to service");
+ if (service == null) Log.w(TAG, "Proxy not attached to service");
return false;
}
@@ -666,15 +667,15 @@
*/
public boolean stopVoiceRecognition(BluetoothDevice device) {
if (DBG) log("stopVoiceRecognition()");
- if (mService != null && isEnabled() &&
- isValidDevice(device)) {
+ final IBluetoothHeadsetClient service = mService;
+ if (service != null && isEnabled() && isValidDevice(device)) {
try {
- return mService.stopVoiceRecognition(device);
+ return service.stopVoiceRecognition(device);
} catch (RemoteException e) {
Log.e(TAG, Log.getStackTraceString(new Throwable()));
}
}
- if (mService == null) Log.w(TAG, "Proxy not attached to service");
+ if (service == null) Log.w(TAG, "Proxy not attached to service");
return false;
}
@@ -686,15 +687,15 @@
*/
public List<BluetoothHeadsetClientCall> getCurrentCalls(BluetoothDevice device) {
if (DBG) log("getCurrentCalls()");
- if (mService != null && isEnabled() &&
- isValidDevice(device)) {
+ final IBluetoothHeadsetClient service = mService;
+ if (service != null && isEnabled() && isValidDevice(device)) {
try {
- return mService.getCurrentCalls(device);
+ return service.getCurrentCalls(device);
} catch (RemoteException e) {
Log.e(TAG, Log.getStackTraceString(new Throwable()));
}
}
- if (mService == null) Log.w(TAG, "Proxy not attached to service");
+ if (service == null) Log.w(TAG, "Proxy not attached to service");
return null;
}
@@ -707,15 +708,15 @@
*/
public Bundle getCurrentAgEvents(BluetoothDevice device) {
if (DBG) log("getCurrentCalls()");
- if (mService != null && isEnabled() &&
- isValidDevice(device)) {
+ final IBluetoothHeadsetClient service = mService;
+ if (service != null && isEnabled() && isValidDevice(device)) {
try {
- return mService.getCurrentAgEvents(device);
+ return service.getCurrentAgEvents(device);
} catch (RemoteException e) {
Log.e(TAG, Log.getStackTraceString(new Throwable()));
}
}
- if (mService == null) Log.w(TAG, "Proxy not attached to service");
+ if (service == null) Log.w(TAG, "Proxy not attached to service");
return null;
}
@@ -733,15 +734,15 @@
*/
public boolean acceptCall(BluetoothDevice device, int flag) {
if (DBG) log("acceptCall()");
- if (mService != null && isEnabled() &&
- isValidDevice(device)) {
+ final IBluetoothHeadsetClient service = mService;
+ if (service != null && isEnabled() && isValidDevice(device)) {
try {
- return mService.acceptCall(device, flag);
+ return service.acceptCall(device, flag);
} catch (RemoteException e) {
Log.e(TAG, Log.getStackTraceString(new Throwable()));
}
}
- if (mService == null) Log.w(TAG, "Proxy not attached to service");
+ if (service == null) Log.w(TAG, "Proxy not attached to service");
return false;
}
@@ -756,15 +757,15 @@
*/
public boolean holdCall(BluetoothDevice device) {
if (DBG) log("holdCall()");
- if (mService != null && isEnabled() &&
- isValidDevice(device)) {
+ final IBluetoothHeadsetClient service = mService;
+ if (service != null && isEnabled() && isValidDevice(device)) {
try {
- return mService.holdCall(device);
+ return service.holdCall(device);
} catch (RemoteException e) {
Log.e(TAG, Log.getStackTraceString(new Throwable()));
}
}
- if (mService == null) Log.w(TAG, "Proxy not attached to service");
+ if (service == null) Log.w(TAG, "Proxy not attached to service");
return false;
}
@@ -783,15 +784,15 @@
*/
public boolean rejectCall(BluetoothDevice device) {
if (DBG) log("rejectCall()");
- if (mService != null && isEnabled() &&
- isValidDevice(device)) {
+ final IBluetoothHeadsetClient service = mService;
+ if (service != null && isEnabled() && isValidDevice(device)) {
try {
- return mService.rejectCall(device);
+ return service.rejectCall(device);
} catch (RemoteException e) {
Log.e(TAG, Log.getStackTraceString(new Throwable()));
}
}
- if (mService == null) Log.w(TAG, "Proxy not attached to service");
+ if (service == null) Log.w(TAG, "Proxy not attached to service");
return false;
}
@@ -802,7 +803,7 @@
*
* @param device remote device
* @param call Handle of call obtained in {@link dial()} or obtained via
- * {@link ACTION_CALL_CHANGED}. {@code call} may be null in which
+ * {@link #ACTION_CALL_CHANGED}. {@code call} may be null in which
* case we will hangup all active calls.
* @return <code>true</code> if command has been issued successfully;
* <code>false</code> otherwise;
@@ -815,15 +816,15 @@
*/
public boolean terminateCall(BluetoothDevice device, BluetoothHeadsetClientCall call) {
if (DBG) log("terminateCall()");
- if (mService != null && isEnabled() &&
- isValidDevice(device)) {
+ final IBluetoothHeadsetClient service = mService;
+ if (service != null && isEnabled() && isValidDevice(device)) {
try {
- return mService.terminateCall(device, call);
+ return service.terminateCall(device, call);
} catch (RemoteException e) {
Log.e(TAG, Log.getStackTraceString(new Throwable()));
}
}
- if (mService == null) Log.w(TAG, "Proxy not attached to service");
+ if (service == null) Log.w(TAG, "Proxy not attached to service");
return false;
}
@@ -845,15 +846,15 @@
*/
public boolean enterPrivateMode(BluetoothDevice device, int index) {
if (DBG) log("enterPrivateMode()");
- if (mService != null && isEnabled() &&
- isValidDevice(device)) {
+ final IBluetoothHeadsetClient service = mService;
+ if (service != null && isEnabled() && isValidDevice(device)) {
try {
- return mService.enterPrivateMode(device, index);
+ return service.enterPrivateMode(device, index);
} catch (RemoteException e) {
Log.e(TAG, Log.getStackTraceString(new Throwable()));
}
}
- if (mService == null) Log.w(TAG, "Proxy not attached to service");
+ if (service == null) Log.w(TAG, "Proxy not attached to service");
return false;
}
@@ -874,15 +875,15 @@
*/
public boolean explicitCallTransfer(BluetoothDevice device) {
if (DBG) log("explicitCallTransfer()");
- if (mService != null && isEnabled() &&
- isValidDevice(device)) {
+ final IBluetoothHeadsetClient service = mService;
+ if (service != null && isEnabled() && isValidDevice(device)) {
try {
- return mService.explicitCallTransfer(device);
+ return service.explicitCallTransfer(device);
} catch (RemoteException e) {
Log.e(TAG, Log.getStackTraceString(new Throwable()));
}
}
- if (mService == null) Log.w(TAG, "Proxy not attached to service");
+ if (service == null) Log.w(TAG, "Proxy not attached to service");
return false;
}
@@ -900,15 +901,15 @@
*/
public BluetoothHeadsetClientCall dial(BluetoothDevice device, String number) {
if (DBG) log("dial()");
- if (mService != null && isEnabled() &&
- isValidDevice(device)) {
+ final IBluetoothHeadsetClient service = mService;
+ if (service != null && isEnabled() && isValidDevice(device)) {
try {
- return mService.dial(device, number);
+ return service.dial(device, number);
} catch (RemoteException e) {
Log.e(TAG, Log.getStackTraceString(new Throwable()));
}
}
- if (mService == null) Log.w(TAG, "Proxy not attached to service");
+ if (service == null) Log.w(TAG, "Proxy not attached to service");
return null;
}
@@ -925,15 +926,15 @@
*/
public boolean sendDTMF(BluetoothDevice device, byte code) {
if (DBG) log("sendDTMF()");
- if (mService != null && isEnabled() &&
- isValidDevice(device)) {
+ final IBluetoothHeadsetClient service = mService;
+ if (service != null && isEnabled() && isValidDevice(device)) {
try {
- return mService.sendDTMF(device, code);
+ return service.sendDTMF(device, code);
} catch (RemoteException e) {
Log.e(TAG, Log.getStackTraceString(new Throwable()));
}
}
- if (mService == null) Log.w(TAG, "Proxy not attached to service");
+ if (service == null) Log.w(TAG, "Proxy not attached to service");
return false;
}
@@ -952,15 +953,15 @@
*/
public boolean getLastVoiceTagNumber(BluetoothDevice device) {
if (DBG) log("getLastVoiceTagNumber()");
- if (mService != null && isEnabled() &&
- isValidDevice(device)) {
+ final IBluetoothHeadsetClient service = mService;
+ if (service != null && isEnabled() && isValidDevice(device)) {
try {
- return mService.getLastVoiceTagNumber(device);
+ return service.getLastVoiceTagNumber(device);
} catch (RemoteException e) {
Log.e(TAG, Log.getStackTraceString(new Throwable()));
}
}
- if (mService == null) Log.w(TAG, "Proxy not attached to service");
+ if (service == null) Log.w(TAG, "Proxy not attached to service");
return false;
}
@@ -971,10 +972,13 @@
*/
public int getAudioState(BluetoothDevice device) {
if (VDBG) log("getAudioState");
- if (mService != null && isEnabled()) {
+ final IBluetoothHeadsetClient service = mService;
+ if (service != null && isEnabled()) {
try {
- return mService.getAudioState(device);
- } catch (RemoteException e) {Log.e(TAG, e.toString());}
+ return service.getAudioState(device);
+ } catch (RemoteException e) {
+ Log.e(TAG, e.toString());
+ }
} else {
Log.w(TAG, "Proxy not attached to service");
if (DBG) Log.d(TAG, Log.getStackTraceString(new Throwable()));
@@ -991,10 +995,13 @@
*/
public void setAudioRouteAllowed(BluetoothDevice device, boolean allowed) {
if (VDBG) log("setAudioRouteAllowed");
- if (mService != null && isEnabled()) {
+ final IBluetoothHeadsetClient service = mService;
+ if (service != null && isEnabled()) {
try {
- mService.setAudioRouteAllowed(device, allowed);
- } catch (RemoteException e) {Log.e(TAG, e.toString());}
+ service.setAudioRouteAllowed(device, allowed);
+ } catch (RemoteException e) {
+ Log.e(TAG, e.toString());
+ }
} else {
Log.w(TAG, "Proxy not attached to service");
if (DBG) Log.d(TAG, Log.getStackTraceString(new Throwable()));
@@ -1009,10 +1016,13 @@
*/
public boolean getAudioRouteAllowed(BluetoothDevice device) {
if (VDBG) log("getAudioRouteAllowed");
- if (mService != null && isEnabled()) {
+ final IBluetoothHeadsetClient service = mService;
+ if (service != null && isEnabled()) {
try {
- return mService.getAudioRouteAllowed(device);
- } catch (RemoteException e) {Log.e(TAG, e.toString());}
+ return service.getAudioRouteAllowed(device);
+ } catch (RemoteException e) {
+ Log.e(TAG, e.toString());
+ }
} else {
Log.w(TAG, "Proxy not attached to service");
if (DBG) Log.d(TAG, Log.getStackTraceString(new Throwable()));
@@ -1032,9 +1042,10 @@
* intent;
*/
public boolean connectAudio(BluetoothDevice device) {
- if (mService != null && isEnabled()) {
+ final IBluetoothHeadsetClient service = mService;
+ if (service != null && isEnabled()) {
try {
- return mService.connectAudio(device);
+ return service.connectAudio(device);
} catch (RemoteException e) {
Log.e(TAG, e.toString());
}
@@ -1057,9 +1068,10 @@
* intent;
*/
public boolean disconnectAudio(BluetoothDevice device) {
- if (mService != null && isEnabled()) {
+ final IBluetoothHeadsetClient service = mService;
+ if (service != null && isEnabled()) {
try {
- return mService.disconnectAudio(device);
+ return service.disconnectAudio(device);
} catch (RemoteException e) {
Log.e(TAG, e.toString());
}
@@ -1078,9 +1090,10 @@
* AG not connected
*/
public Bundle getCurrentAgFeatures(BluetoothDevice device) {
- if (mService != null && isEnabled()) {
+ final IBluetoothHeadsetClient service = mService;
+ if (service != null && isEnabled()) {
try {
- return mService.getCurrentAgFeatures(device);
+ return service.getCurrentAgFeatures(device);
} catch (RemoteException e) {
Log.e(TAG, e.toString());
}
@@ -1092,7 +1105,7 @@
}
- private ServiceConnection mConnection = new ServiceConnection() {
+ private final ServiceConnection mConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName className, IBinder service) {
if (DBG) Log.d(TAG, "Proxy object connected");
@@ -1114,15 +1127,11 @@
};
private boolean isEnabled() {
- if (mAdapter.getState() == BluetoothAdapter.STATE_ON) return true;
- return false;
+ return mAdapter.getState() == BluetoothAdapter.STATE_ON;
}
- private boolean isValidDevice(BluetoothDevice device) {
- if (device == null) return false;
-
- if (BluetoothAdapter.checkBluetoothAddress(device.getAddress())) return true;
- return false;
+ private static boolean isValidDevice(BluetoothDevice device) {
+ return device != null && BluetoothAdapter.checkBluetoothAddress(device.getAddress());
}
private static void log(String msg) {
diff --git a/core/java/android/bluetooth/BluetoothHealth.java b/core/java/android/bluetooth/BluetoothHealth.java
index 8d77888..07be63f 100644
--- a/core/java/android/bluetooth/BluetoothHealth.java
+++ b/core/java/android/bluetooth/BluetoothHealth.java
@@ -178,9 +178,10 @@
BluetoothHealthAppConfiguration config =
new BluetoothHealthAppConfiguration(name, dataType, role, channelType);
- if (mService != null) {
+ final IBluetoothHealth service = mService;
+ if (service != null) {
try {
- result = mService.registerAppConfiguration(config, wrapper);
+ result = service.registerAppConfiguration(config, wrapper);
} catch (RemoteException e) {
Log.e(TAG, e.toString());
}
@@ -202,9 +203,10 @@
*/
public boolean unregisterAppConfiguration(BluetoothHealthAppConfiguration config) {
boolean result = false;
- if (mService != null && isEnabled() && config != null) {
+ final IBluetoothHealth service = mService;
+ if (service != null && isEnabled() && config != null) {
try {
- result = mService.unregisterAppConfiguration(config);
+ result = service.unregisterAppConfiguration(config);
} catch (RemoteException e) {
Log.e(TAG, e.toString());
}
@@ -230,10 +232,10 @@
*/
public boolean connectChannelToSource(BluetoothDevice device,
BluetoothHealthAppConfiguration config) {
- if (mService != null && isEnabled() && isValidDevice(device) &&
- config != null) {
+ final IBluetoothHealth service = mService;
+ if (service != null && isEnabled() && isValidDevice(device) && config != null) {
try {
- return mService.connectChannelToSource(device, config);
+ return service.connectChannelToSource(device, config);
} catch (RemoteException e) {
Log.e(TAG, e.toString());
}
@@ -259,10 +261,10 @@
*/
public boolean connectChannelToSink(BluetoothDevice device,
BluetoothHealthAppConfiguration config, int channelType) {
- if (mService != null && isEnabled() && isValidDevice(device) &&
- config != null) {
+ final IBluetoothHealth service = mService;
+ if (service != null && isEnabled() && isValidDevice(device) && config != null) {
try {
- return mService.connectChannelToSink(device, config, channelType);
+ return service.connectChannelToSink(device, config, channelType);
} catch (RemoteException e) {
Log.e(TAG, e.toString());
}
@@ -288,10 +290,10 @@
*/
public boolean disconnectChannel(BluetoothDevice device,
BluetoothHealthAppConfiguration config, int channelId) {
- if (mService != null && isEnabled() && isValidDevice(device) &&
- config != null) {
+ final IBluetoothHealth service = mService;
+ if (service != null && isEnabled() && isValidDevice(device) && config != null) {
try {
- return mService.disconnectChannel(device, config, channelId);
+ return service.disconnectChannel(device, config, channelId);
} catch (RemoteException e) {
Log.e(TAG, e.toString());
}
@@ -317,10 +319,10 @@
*/
public ParcelFileDescriptor getMainChannelFd(BluetoothDevice device,
BluetoothHealthAppConfiguration config) {
- if (mService != null && isEnabled() && isValidDevice(device) &&
- config != null) {
+ final IBluetoothHealth service = mService;
+ if (service != null && isEnabled() && isValidDevice(device) && config != null) {
try {
- return mService.getMainChannelFd(device, config);
+ return service.getMainChannelFd(device, config);
} catch (RemoteException e) {
Log.e(TAG, e.toString());
}
@@ -348,9 +350,10 @@
*/
@Override
public int getConnectionState(BluetoothDevice device) {
- if (mService != null && isEnabled() && isValidDevice(device)) {
+ final IBluetoothHealth service = mService;
+ if (service != null && isEnabled() && isValidDevice(device)) {
try {
- return mService.getHealthDeviceConnectionState(device);
+ return service.getHealthDeviceConnectionState(device);
} catch (RemoteException e) {
Log.e(TAG, e.toString());
}
@@ -376,15 +379,16 @@
*/
@Override
public List<BluetoothDevice> getConnectedDevices() {
- if (mService != null && isEnabled()) {
+ final IBluetoothHealth service = mService;
+ if (service != null && isEnabled()) {
try {
- return mService.getConnectedHealthDevices();
+ return service.getConnectedHealthDevices();
} catch (RemoteException e) {
Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
return new ArrayList<BluetoothDevice>();
}
}
- if (mService == null) Log.w(TAG, "Proxy not attached to service");
+ if (service == null) Log.w(TAG, "Proxy not attached to service");
return new ArrayList<BluetoothDevice>();
}
@@ -408,15 +412,16 @@
*/
@Override
public List<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states) {
- if (mService != null && isEnabled()) {
+ final IBluetoothHealth service = mService;
+ if (service != null && isEnabled()) {
try {
- return mService.getHealthDevicesMatchingConnectionStates(states);
+ return service.getHealthDevicesMatchingConnectionStates(states);
} catch (RemoteException e) {
Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
return new ArrayList<BluetoothDevice>();
}
}
- if (mService == null) Log.w(TAG, "Proxy not attached to service");
+ if (service == null) Log.w(TAG, "Proxy not attached to service");
return new ArrayList<BluetoothDevice>();
}
@@ -462,7 +467,7 @@
private Context mContext;
private ServiceListener mServiceListener;
- private IBluetoothHealth mService;
+ private volatile IBluetoothHealth mService;
BluetoothAdapter mAdapter;
/**
@@ -546,11 +551,8 @@
return false;
}
- private boolean isValidDevice(BluetoothDevice device) {
- if (device == null) return false;
-
- if (BluetoothAdapter.checkBluetoothAddress(device.getAddress())) return true;
- return false;
+ private static boolean isValidDevice(BluetoothDevice device) {
+ return device != null && BluetoothAdapter.checkBluetoothAddress(device.getAddress());
}
private boolean checkAppParam(String name, int role, int channelType,
diff --git a/core/java/android/bluetooth/BluetoothInputDevice.java b/core/java/android/bluetooth/BluetoothInputDevice.java
index a5a0243..07966ed 100644
--- a/core/java/android/bluetooth/BluetoothInputDevice.java
+++ b/core/java/android/bluetooth/BluetoothInputDevice.java
@@ -214,7 +214,7 @@
private Context mContext;
private ServiceListener mServiceListener;
private BluetoothAdapter mAdapter;
- private IBluetoothInputDevice mService;
+ private volatile IBluetoothInputDevice mService;
final private IBluetoothStateChangeCallback mBluetoothStateChangeCallback =
new IBluetoothStateChangeCallback.Stub() {
@@ -325,15 +325,16 @@
*/
public boolean connect(BluetoothDevice device) {
if (DBG) log("connect(" + device + ")");
- if (mService != null && isEnabled() && isValidDevice(device)) {
+ final IBluetoothInputDevice service = mService;
+ if (service != null && isEnabled() && isValidDevice(device)) {
try {
- return mService.connect(device);
+ return service.connect(device);
} catch (RemoteException e) {
Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
return false;
}
}
- if (mService == null) Log.w(TAG, "Proxy not attached to service");
+ if (service == null) Log.w(TAG, "Proxy not attached to service");
return false;
}
@@ -365,15 +366,16 @@
*/
public boolean disconnect(BluetoothDevice device) {
if (DBG) log("disconnect(" + device + ")");
- if (mService != null && isEnabled() && isValidDevice(device)) {
+ final IBluetoothInputDevice service = mService;
+ if (service != null && isEnabled() && isValidDevice(device)) {
try {
- return mService.disconnect(device);
+ return service.disconnect(device);
} catch (RemoteException e) {
Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
return false;
}
}
- if (mService == null) Log.w(TAG, "Proxy not attached to service");
+ if (service == null) Log.w(TAG, "Proxy not attached to service");
return false;
}
@@ -382,15 +384,16 @@
*/
public List<BluetoothDevice> getConnectedDevices() {
if (VDBG) log("getConnectedDevices()");
- if (mService != null && isEnabled()) {
+ final IBluetoothInputDevice service = mService;
+ if (service != null && isEnabled()) {
try {
- return mService.getConnectedDevices();
+ return service.getConnectedDevices();
} catch (RemoteException e) {
Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
return new ArrayList<BluetoothDevice>();
}
}
- if (mService == null) Log.w(TAG, "Proxy not attached to service");
+ if (service == null) Log.w(TAG, "Proxy not attached to service");
return new ArrayList<BluetoothDevice>();
}
@@ -399,15 +402,16 @@
*/
public List<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states) {
if (VDBG) log("getDevicesMatchingStates()");
- if (mService != null && isEnabled()) {
+ final IBluetoothInputDevice service = mService;
+ if (service != null && isEnabled()) {
try {
- return mService.getDevicesMatchingConnectionStates(states);
+ return service.getDevicesMatchingConnectionStates(states);
} catch (RemoteException e) {
Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
return new ArrayList<BluetoothDevice>();
}
}
- if (mService == null) Log.w(TAG, "Proxy not attached to service");
+ if (service == null) Log.w(TAG, "Proxy not attached to service");
return new ArrayList<BluetoothDevice>();
}
@@ -416,15 +420,16 @@
*/
public int getConnectionState(BluetoothDevice device) {
if (VDBG) log("getState(" + device + ")");
- if (mService != null && isEnabled() && isValidDevice(device)) {
+ final IBluetoothInputDevice service = mService;
+ if (service != null && isEnabled() && isValidDevice(device)) {
try {
- return mService.getConnectionState(device);
+ return service.getConnectionState(device);
} catch (RemoteException e) {
Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
return BluetoothProfile.STATE_DISCONNECTED;
}
}
- if (mService == null) Log.w(TAG, "Proxy not attached to service");
+ if (service == null) Log.w(TAG, "Proxy not attached to service");
return BluetoothProfile.STATE_DISCONNECTED;
}
@@ -445,19 +450,20 @@
*/
public boolean setPriority(BluetoothDevice device, int priority) {
if (DBG) log("setPriority(" + device + ", " + priority + ")");
- if (mService != null && isEnabled() && isValidDevice(device)) {
- if (priority != BluetoothProfile.PRIORITY_OFF &&
- priority != BluetoothProfile.PRIORITY_ON) {
- return false;
+ final IBluetoothInputDevice service = mService;
+ if (service != null && isEnabled() && isValidDevice(device)) {
+ if (priority != BluetoothProfile.PRIORITY_OFF
+ && priority != BluetoothProfile.PRIORITY_ON) {
+ return false;
}
try {
- return mService.setPriority(device, priority);
+ return service.setPriority(device, priority);
} catch (RemoteException e) {
Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
return false;
}
}
- if (mService == null) Log.w(TAG, "Proxy not attached to service");
+ if (service == null) Log.w(TAG, "Proxy not attached to service");
return false;
}
@@ -476,15 +482,16 @@
*/
public int getPriority(BluetoothDevice device) {
if (VDBG) log("getPriority(" + device + ")");
- if (mService != null && isEnabled() && isValidDevice(device)) {
+ final IBluetoothInputDevice service = mService;
+ if (service != null && isEnabled() && isValidDevice(device)) {
try {
- return mService.getPriority(device);
+ return service.getPriority(device);
} catch (RemoteException e) {
Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
return BluetoothProfile.PRIORITY_OFF;
}
}
- if (mService == null) Log.w(TAG, "Proxy not attached to service");
+ if (service == null) Log.w(TAG, "Proxy not attached to service");
return BluetoothProfile.PRIORITY_OFF;
}
@@ -507,18 +514,13 @@
};
private boolean isEnabled() {
- if (mAdapter.getState() == BluetoothAdapter.STATE_ON) return true;
- return false;
+ return mAdapter.getState() == BluetoothAdapter.STATE_ON;
}
- private boolean isValidDevice(BluetoothDevice device) {
- if (device == null) return false;
-
- if (BluetoothAdapter.checkBluetoothAddress(device.getAddress())) return true;
- return false;
+ private static boolean isValidDevice(BluetoothDevice device) {
+ return device != null && BluetoothAdapter.checkBluetoothAddress(device.getAddress());
}
-
/**
* Initiate virtual unplug for a HID input device.
*
@@ -531,16 +533,17 @@
*/
public boolean virtualUnplug(BluetoothDevice device) {
if (DBG) log("virtualUnplug(" + device + ")");
- if (mService != null && isEnabled() && isValidDevice(device)) {
+ final IBluetoothInputDevice service = mService;
+ if (service != null && isEnabled() && isValidDevice(device)) {
try {
- return mService.virtualUnplug(device);
+ return service.virtualUnplug(device);
} catch (RemoteException e) {
Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
return false;
}
}
- if (mService == null) Log.w(TAG, "Proxy not attached to service");
+ if (service == null) Log.w(TAG, "Proxy not attached to service");
return false;
}
@@ -557,16 +560,17 @@
*/
public boolean getProtocolMode(BluetoothDevice device) {
if (VDBG) log("getProtocolMode(" + device + ")");
- if (mService != null && isEnabled() && isValidDevice(device)) {
+ final IBluetoothInputDevice service = mService;
+ if (service != null && isEnabled() && isValidDevice(device)) {
try {
- return mService.getProtocolMode(device);
+ return service.getProtocolMode(device);
} catch (RemoteException e) {
Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
return false;
}
}
- if (mService == null) Log.w(TAG, "Proxy not attached to service");
- return false;
+ if (service == null) Log.w(TAG, "Proxy not attached to service");
+ return false;
}
/**
@@ -581,15 +585,16 @@
*/
public boolean setProtocolMode(BluetoothDevice device, int protocolMode) {
if (DBG) log("setProtocolMode(" + device + ")");
- if (mService != null && isEnabled() && isValidDevice(device)) {
+ final IBluetoothInputDevice service = mService;
+ if (service != null && isEnabled() && isValidDevice(device)) {
try {
- return mService.setProtocolMode(device, protocolMode);
+ return service.setProtocolMode(device, protocolMode);
} catch (RemoteException e) {
Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
return false;
}
}
- if (mService == null) Log.w(TAG, "Proxy not attached to service");
+ if (service == null) Log.w(TAG, "Proxy not attached to service");
return false;
}
@@ -606,17 +611,22 @@
* true otherwise
* @hide
*/
- public boolean getReport(BluetoothDevice device, byte reportType, byte reportId, int bufferSize) {
- if (VDBG) log("getReport(" + device + "), reportType=" + reportType + " reportId=" + reportId + "bufferSize=" + bufferSize);
- if (mService != null && isEnabled() && isValidDevice(device)) {
+ public boolean getReport(BluetoothDevice device, byte reportType, byte reportId,
+ int bufferSize) {
+ if (VDBG) {
+ log("getReport(" + device + "), reportType=" + reportType + " reportId=" + reportId
+ + "bufferSize=" + bufferSize);
+ }
+ final IBluetoothInputDevice service = mService;
+ if (service != null && isEnabled() && isValidDevice(device)) {
try {
- return mService.getReport(device, reportType, reportId, bufferSize);
+ return service.getReport(device, reportType, reportId, bufferSize);
} catch (RemoteException e) {
Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
return false;
}
}
- if (mService == null) Log.w(TAG, "Proxy not attached to service");
+ if (service == null) Log.w(TAG, "Proxy not attached to service");
return false;
}
@@ -634,15 +644,16 @@
*/
public boolean setReport(BluetoothDevice device, byte reportType, String report) {
if (VDBG) log("setReport(" + device + "), reportType=" + reportType + " report=" + report);
- if (mService != null && isEnabled() && isValidDevice(device)) {
+ final IBluetoothInputDevice service = mService;
+ if (service != null && isEnabled() && isValidDevice(device)) {
try {
- return mService.setReport(device, reportType, report);
+ return service.setReport(device, reportType, report);
} catch (RemoteException e) {
Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
return false;
}
}
- if (mService == null) Log.w(TAG, "Proxy not attached to service");
+ if (service == null) Log.w(TAG, "Proxy not attached to service");
return false;
}
@@ -659,15 +670,16 @@
*/
public boolean sendData(BluetoothDevice device, String report) {
if (DBG) log("sendData(" + device + "), report=" + report);
- if (mService != null && isEnabled() && isValidDevice(device)) {
+ final IBluetoothInputDevice service = mService;
+ if (service != null && isEnabled() && isValidDevice(device)) {
try {
- return mService.sendData(device, report);
+ return service.sendData(device, report);
} catch (RemoteException e) {
Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
return false;
}
}
- if (mService == null) Log.w(TAG, "Proxy not attached to service");
+ if (service == null) Log.w(TAG, "Proxy not attached to service");
return false;
}
@@ -683,15 +695,16 @@
*/
public boolean getIdleTime(BluetoothDevice device) {
if (DBG) log("getIdletime(" + device + ")");
- if (mService != null && isEnabled() && isValidDevice(device)) {
+ final IBluetoothInputDevice service = mService;
+ if (service != null && isEnabled() && isValidDevice(device)) {
try {
- return mService.getIdleTime(device);
+ return service.getIdleTime(device);
} catch (RemoteException e) {
Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
return false;
}
}
- if (mService == null) Log.w(TAG, "Proxy not attached to service");
+ if (service == null) Log.w(TAG, "Proxy not attached to service");
return false;
}
@@ -708,15 +721,16 @@
*/
public boolean setIdleTime(BluetoothDevice device, byte idleTime) {
if (DBG) log("setIdletime(" + device + "), idleTime=" + idleTime);
- if (mService != null && isEnabled() && isValidDevice(device)) {
+ final IBluetoothInputDevice service = mService;
+ if (service != null && isEnabled() && isValidDevice(device)) {
try {
- return mService.setIdleTime(device, idleTime);
+ return service.setIdleTime(device, idleTime);
} catch (RemoteException e) {
Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
return false;
}
}
- if (mService == null) Log.w(TAG, "Proxy not attached to service");
+ if (service == null) Log.w(TAG, "Proxy not attached to service");
return false;
}
diff --git a/core/java/android/bluetooth/BluetoothInputHost.java b/core/java/android/bluetooth/BluetoothInputHost.java
index 68d105f..6a0506d 100644
--- a/core/java/android/bluetooth/BluetoothInputHost.java
+++ b/core/java/android/bluetooth/BluetoothInputHost.java
@@ -26,8 +26,8 @@
import android.os.RemoteException;
import android.util.Log;
-import java.util.Arrays;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.List;
/**
@@ -114,7 +114,7 @@
private ServiceListener mServiceListener;
- private IBluetoothInputHost mService;
+ private volatile IBluetoothInputHost mService;
private BluetoothAdapter mAdapter;
@@ -195,24 +195,18 @@
}
};
- private ServiceConnection mConnection = new ServiceConnection() {
-
+ private final ServiceConnection mConnection = new ServiceConnection() {
public void onServiceConnected(ComponentName className, IBinder service) {
Log.d(TAG, "onServiceConnected()");
-
mService = IBluetoothInputHost.Stub.asInterface(service);
-
if (mServiceListener != null) {
mServiceListener.onServiceConnected(BluetoothProfile.INPUT_HOST,
BluetoothInputHost.this);
}
}
-
public void onServiceDisconnected(ComponentName className) {
Log.d(TAG, "onServiceDisconnected()");
-
mService = null;
-
if (mServiceListener != null) {
mServiceListener.onServiceDisconnected(BluetoothProfile.INPUT_HOST);
}
@@ -283,9 +277,10 @@
public List<BluetoothDevice> getConnectedDevices() {
Log.v(TAG, "getConnectedDevices()");
- if (mService != null) {
+ final IBluetoothInputHost service = mService;
+ if (service != null) {
try {
- return mService.getConnectedDevices();
+ return service.getConnectedDevices();
} catch (RemoteException e) {
Log.e(TAG, e.toString());
}
@@ -302,9 +297,10 @@
public List<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states) {
Log.v(TAG, "getDevicesMatchingConnectionStates(): states=" + Arrays.toString(states));
- if (mService != null) {
+ final IBluetoothInputHost service = mService;
+ if (service != null) {
try {
- return mService.getDevicesMatchingConnectionStates(states);
+ return service.getDevicesMatchingConnectionStates(states);
} catch (RemoteException e) {
Log.e(TAG, e.toString());
}
@@ -321,9 +317,10 @@
public int getConnectionState(BluetoothDevice device) {
Log.v(TAG, "getConnectionState(): device=" + device);
- if (mService != null) {
+ final IBluetoothInputHost service = mService;
+ if (service != null) {
try {
- return mService.getConnectionState(device);
+ return service.getConnectionState(device);
} catch (RemoteException e) {
Log.e(TAG, e.toString());
}
@@ -363,13 +360,14 @@
return false;
}
- if (mService != null) {
+ final IBluetoothInputHost service = mService;
+ if (service != null) {
try {
BluetoothHidDeviceAppConfiguration config =
- new BluetoothHidDeviceAppConfiguration();
+ new BluetoothHidDeviceAppConfiguration();
BluetoothHidDeviceCallbackWrapper cbw =
- new BluetoothHidDeviceCallbackWrapper(callback);
- result = mService.registerApp(config, sdp, inQos, outQos, cbw);
+ new BluetoothHidDeviceCallbackWrapper(callback);
+ result = service.registerApp(config, sdp, inQos, outQos, cbw);
} catch (RemoteException e) {
Log.e(TAG, e.toString());
}
@@ -397,9 +395,10 @@
boolean result = false;
- if (mService != null) {
+ final IBluetoothInputHost service = mService;
+ if (service != null) {
try {
- result = mService.unregisterApp(config);
+ result = service.unregisterApp(config);
} catch (RemoteException e) {
Log.e(TAG, e.toString());
}
@@ -421,9 +420,10 @@
public boolean sendReport(BluetoothDevice device, int id, byte[] data) {
boolean result = false;
- if (mService != null) {
+ final IBluetoothInputHost service = mService;
+ if (service != null) {
try {
- result = mService.sendReport(device, id, data);
+ result = service.sendReport(device, id, data);
} catch (RemoteException e) {
Log.e(TAG, e.toString());
}
@@ -448,9 +448,10 @@
boolean result = false;
- if (mService != null) {
+ final IBluetoothInputHost service = mService;
+ if (service != null) {
try {
- result = mService.replyReport(device, type, id, data);
+ result = service.replyReport(device, type, id, data);
} catch (RemoteException e) {
Log.e(TAG, e.toString());
}
@@ -473,9 +474,10 @@
boolean result = false;
- if (mService != null) {
+ final IBluetoothInputHost service = mService;
+ if (service != null) {
try {
- result = mService.reportError(device, error);
+ result = service.reportError(device, error);
} catch (RemoteException e) {
Log.e(TAG, e.toString());
}
@@ -496,9 +498,10 @@
boolean result = false;
- if (mService != null) {
+ final IBluetoothInputHost service = mService;
+ if (service != null) {
try {
- result = mService.unplug(device);
+ result = service.unplug(device);
} catch (RemoteException e) {
Log.e(TAG, e.toString());
}
@@ -520,9 +523,10 @@
boolean result = false;
- if (mService != null) {
+ final IBluetoothInputHost service = mService;
+ if (service != null) {
try {
- result = mService.connect(device);
+ result = service.connect(device);
} catch (RemoteException e) {
Log.e(TAG, e.toString());
}
@@ -543,9 +547,10 @@
boolean result = false;
- if (mService != null) {
+ final IBluetoothInputHost service = mService;
+ if (service != null) {
try {
- result = mService.disconnect(device);
+ result = service.disconnect(device);
} catch (RemoteException e) {
Log.e(TAG, e.toString());
}
diff --git a/core/java/android/bluetooth/BluetoothMap.java b/core/java/android/bluetooth/BluetoothMap.java
index 2e73051..0f801fd 100644
--- a/core/java/android/bluetooth/BluetoothMap.java
+++ b/core/java/android/bluetooth/BluetoothMap.java
@@ -16,15 +16,18 @@
package android.bluetooth;
-import java.util.List;
-import java.util.ArrayList;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
-import android.os.*;
+import android.os.Binder;
+import android.os.IBinder;
+import android.os.RemoteException;
import android.util.Log;
+import java.util.ArrayList;
+import java.util.List;
+
/**
* This class provides the APIs to control the Bluetooth MAP
* Profile.
@@ -39,7 +42,7 @@
public static final String ACTION_CONNECTION_STATE_CHANGED =
"android.bluetooth.map.profile.action.CONNECTION_STATE_CHANGED";
- private IBluetoothMap mService;
+ private volatile IBluetoothMap mService;
private final Context mContext;
private ServiceListener mServiceListener;
private BluetoothAdapter mAdapter;
@@ -156,10 +159,13 @@
*/
public int getState() {
if (VDBG) log("getState()");
- if (mService != null) {
+ final IBluetoothMap service = mService;
+ if (service != null) {
try {
- return mService.getState();
- } catch (RemoteException e) {Log.e(TAG, e.toString());}
+ return service.getState();
+ } catch (RemoteException e) {
+ Log.e(TAG, e.toString());
+ }
} else {
Log.w(TAG, "Proxy not attached to service");
if (DBG) log(Log.getStackTraceString(new Throwable()));
@@ -175,10 +181,13 @@
*/
public BluetoothDevice getClient() {
if (VDBG) log("getClient()");
- if (mService != null) {
+ final IBluetoothMap service = mService;
+ if (service != null) {
try {
- return mService.getClient();
- } catch (RemoteException e) {Log.e(TAG, e.toString());}
+ return service.getClient();
+ } catch (RemoteException e) {
+ Log.e(TAG, e.toString());
+ }
} else {
Log.w(TAG, "Proxy not attached to service");
if (DBG) log(Log.getStackTraceString(new Throwable()));
@@ -193,10 +202,13 @@
*/
public boolean isConnected(BluetoothDevice device) {
if (VDBG) log("isConnected(" + device + ")");
- if (mService != null) {
+ final IBluetoothMap service = mService;
+ if (service != null) {
try {
- return mService.isConnected(device);
- } catch (RemoteException e) {Log.e(TAG, e.toString());}
+ return service.isConnected(device);
+ } catch (RemoteException e) {
+ Log.e(TAG, e.toString());
+ }
} else {
Log.w(TAG, "Proxy not attached to service");
if (DBG) log(Log.getStackTraceString(new Throwable()));
@@ -222,16 +234,16 @@
*/
public boolean disconnect(BluetoothDevice device) {
if (DBG) log("disconnect(" + device + ")");
- if (mService != null && isEnabled() &&
- isValidDevice(device)) {
+ final IBluetoothMap service = mService;
+ if (service != null && isEnabled() && isValidDevice(device)) {
try {
- return mService.disconnect(device);
+ return service.disconnect(device);
} catch (RemoteException e) {
Log.e(TAG, Log.getStackTraceString(new Throwable()));
return false;
}
}
- if (mService == null) Log.w(TAG, "Proxy not attached to service");
+ if (service == null) Log.w(TAG, "Proxy not attached to service");
return false;
}
@@ -262,15 +274,16 @@
*/
public List<BluetoothDevice> getConnectedDevices() {
if (DBG) log("getConnectedDevices()");
- if (mService != null && isEnabled()) {
+ final IBluetoothMap service = mService;
+ if (service != null && isEnabled()) {
try {
- return mService.getConnectedDevices();
+ return service.getConnectedDevices();
} catch (RemoteException e) {
Log.e(TAG, Log.getStackTraceString(new Throwable()));
return new ArrayList<BluetoothDevice>();
}
}
- if (mService == null) Log.w(TAG, "Proxy not attached to service");
+ if (service == null) Log.w(TAG, "Proxy not attached to service");
return new ArrayList<BluetoothDevice>();
}
@@ -281,15 +294,16 @@
*/
public List<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states) {
if (DBG) log("getDevicesMatchingStates()");
- if (mService != null && isEnabled()) {
+ final IBluetoothMap service = mService;
+ if (service != null && isEnabled()) {
try {
- return mService.getDevicesMatchingConnectionStates(states);
+ return service.getDevicesMatchingConnectionStates(states);
} catch (RemoteException e) {
Log.e(TAG, Log.getStackTraceString(new Throwable()));
return new ArrayList<BluetoothDevice>();
}
}
- if (mService == null) Log.w(TAG, "Proxy not attached to service");
+ if (service == null) Log.w(TAG, "Proxy not attached to service");
return new ArrayList<BluetoothDevice>();
}
@@ -300,16 +314,16 @@
*/
public int getConnectionState(BluetoothDevice device) {
if (DBG) log("getConnectionState(" + device + ")");
- if (mService != null && isEnabled() &&
- isValidDevice(device)) {
+ final IBluetoothMap service = mService;
+ if (service != null && isEnabled() && isValidDevice(device)) {
try {
- return mService.getConnectionState(device);
+ return service.getConnectionState(device);
} catch (RemoteException e) {
Log.e(TAG, Log.getStackTraceString(new Throwable()));
return BluetoothProfile.STATE_DISCONNECTED;
}
}
- if (mService == null) Log.w(TAG, "Proxy not attached to service");
+ if (service == null) Log.w(TAG, "Proxy not attached to service");
return BluetoothProfile.STATE_DISCONNECTED;
}
@@ -326,20 +340,20 @@
*/
public boolean setPriority(BluetoothDevice device, int priority) {
if (DBG) log("setPriority(" + device + ", " + priority + ")");
- if (mService != null && isEnabled() &&
- isValidDevice(device)) {
- if (priority != BluetoothProfile.PRIORITY_OFF &&
- priority != BluetoothProfile.PRIORITY_ON) {
- return false;
+ final IBluetoothMap service = mService;
+ if (service != null && isEnabled() && isValidDevice(device)) {
+ if (priority != BluetoothProfile.PRIORITY_OFF
+ && priority != BluetoothProfile.PRIORITY_ON) {
+ return false;
}
try {
- return mService.setPriority(device, priority);
+ return service.setPriority(device, priority);
} catch (RemoteException e) {
Log.e(TAG, Log.getStackTraceString(new Throwable()));
return false;
}
}
- if (mService == null) Log.w(TAG, "Proxy not attached to service");
+ if (service == null) Log.w(TAG, "Proxy not attached to service");
return false;
}
@@ -355,16 +369,16 @@
*/
public int getPriority(BluetoothDevice device) {
if (VDBG) log("getPriority(" + device + ")");
- if (mService != null && isEnabled() &&
- isValidDevice(device)) {
+ final IBluetoothMap service = mService;
+ if (service != null && isEnabled() && isValidDevice(device)) {
try {
- return mService.getPriority(device);
+ return service.getPriority(device);
} catch (RemoteException e) {
Log.e(TAG, Log.getStackTraceString(new Throwable()));
return PRIORITY_OFF;
}
}
- if (mService == null) Log.w(TAG, "Proxy not attached to service");
+ if (service == null) Log.w(TAG, "Proxy not attached to service");
return PRIORITY_OFF;
}
@@ -395,12 +409,8 @@
log("Bluetooth is Not enabled");
return false;
}
- private boolean isValidDevice(BluetoothDevice device) {
- if (device == null) return false;
-
- if (BluetoothAdapter.checkBluetoothAddress(device.getAddress())) return true;
- return false;
+ private static boolean isValidDevice(BluetoothDevice device) {
+ return device != null && BluetoothAdapter.checkBluetoothAddress(device.getAddress());
}
-
}
diff --git a/core/java/android/bluetooth/BluetoothMapClient.java b/core/java/android/bluetooth/BluetoothMapClient.java
index ccab3cd..b8fadf4 100644
--- a/core/java/android/bluetooth/BluetoothMapClient.java
+++ b/core/java/android/bluetooth/BluetoothMapClient.java
@@ -59,7 +59,7 @@
public static final String EXTRA_SENDER_CONTACT_NAME =
"android.bluetooth.mapmce.profile.extra.SENDER_CONTACT_NAME";
- private IBluetoothMapClient mService;
+ private volatile IBluetoothMapClient mService;
private final Context mContext;
private ServiceListener mServiceListener;
private BluetoothAdapter mAdapter;
@@ -176,9 +176,10 @@
*/
public boolean isConnected(BluetoothDevice device) {
if (VDBG) Log.d(TAG, "isConnected(" + device + ")");
- if (mService != null) {
+ final IBluetoothMapClient service = mService;
+ if (service != null) {
try {
- return mService.isConnected(device);
+ return service.isConnected(device);
} catch (RemoteException e) {
Log.e(TAG, e.toString());
}
@@ -195,9 +196,10 @@
*/
public boolean connect(BluetoothDevice device) {
if (DBG) Log.d(TAG, "connect(" + device + ")" + "for MAPS MCE");
- if (mService != null) {
+ final IBluetoothMapClient service = mService;
+ if (service != null) {
try {
- return mService.connect(device);
+ return service.connect(device);
} catch (RemoteException e) {
Log.e(TAG, e.toString());
}
@@ -216,15 +218,15 @@
*/
public boolean disconnect(BluetoothDevice device) {
if (DBG) Log.d(TAG, "disconnect(" + device + ")");
- if (mService != null && isEnabled() &&
- isValidDevice(device)) {
+ final IBluetoothMapClient service = mService;
+ if (service != null && isEnabled() && isValidDevice(device)) {
try {
- return mService.disconnect(device);
+ return service.disconnect(device);
} catch (RemoteException e) {
Log.e(TAG, Log.getStackTraceString(new Throwable()));
}
}
- if (mService == null) Log.w(TAG, "Proxy not attached to service");
+ if (service == null) Log.w(TAG, "Proxy not attached to service");
return false;
}
@@ -236,15 +238,16 @@
@Override
public List<BluetoothDevice> getConnectedDevices() {
if (DBG) Log.d(TAG, "getConnectedDevices()");
- if (mService != null && isEnabled()) {
+ final IBluetoothMapClient service = mService;
+ if (service != null && isEnabled()) {
try {
- return mService.getConnectedDevices();
+ return service.getConnectedDevices();
} catch (RemoteException e) {
Log.e(TAG, Log.getStackTraceString(new Throwable()));
return new ArrayList<>();
}
}
- if (mService == null) Log.w(TAG, "Proxy not attached to service");
+ if (service == null) Log.w(TAG, "Proxy not attached to service");
return new ArrayList<>();
}
@@ -256,15 +259,16 @@
@Override
public List<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states) {
if (DBG) Log.d(TAG, "getDevicesMatchingStates()");
- if (mService != null && isEnabled()) {
+ final IBluetoothMapClient service = mService;
+ if (service != null && isEnabled()) {
try {
- return mService.getDevicesMatchingConnectionStates(states);
+ return service.getDevicesMatchingConnectionStates(states);
} catch (RemoteException e) {
Log.e(TAG, Log.getStackTraceString(new Throwable()));
return new ArrayList<>();
}
}
- if (mService == null) Log.w(TAG, "Proxy not attached to service");
+ if (service == null) Log.w(TAG, "Proxy not attached to service");
return new ArrayList<>();
}
@@ -276,16 +280,16 @@
@Override
public int getConnectionState(BluetoothDevice device) {
if (DBG) Log.d(TAG, "getConnectionState(" + device + ")");
- if (mService != null && isEnabled() &&
- isValidDevice(device)) {
+ final IBluetoothMapClient service = mService;
+ if (service != null && isEnabled() && isValidDevice(device)) {
try {
- return mService.getConnectionState(device);
+ return service.getConnectionState(device);
} catch (RemoteException e) {
Log.e(TAG, Log.getStackTraceString(new Throwable()));
return BluetoothProfile.STATE_DISCONNECTED;
}
}
- if (mService == null) Log.w(TAG, "Proxy not attached to service");
+ if (service == null) Log.w(TAG, "Proxy not attached to service");
return BluetoothProfile.STATE_DISCONNECTED;
}
@@ -300,20 +304,20 @@
*/
public boolean setPriority(BluetoothDevice device, int priority) {
if (DBG) Log.d(TAG, "setPriority(" + device + ", " + priority + ")");
- if (mService != null && isEnabled() &&
- isValidDevice(device)) {
- if (priority != BluetoothProfile.PRIORITY_OFF &&
- priority != BluetoothProfile.PRIORITY_ON) {
+ final IBluetoothMapClient service = mService;
+ if (service != null && isEnabled() && isValidDevice(device)) {
+ if (priority != BluetoothProfile.PRIORITY_OFF
+ && priority != BluetoothProfile.PRIORITY_ON) {
return false;
}
try {
- return mService.setPriority(device, priority);
+ return service.setPriority(device, priority);
} catch (RemoteException e) {
Log.e(TAG, Log.getStackTraceString(new Throwable()));
return false;
}
}
- if (mService == null) Log.w(TAG, "Proxy not attached to service");
+ if (service == null) Log.w(TAG, "Proxy not attached to service");
return false;
}
@@ -329,16 +333,16 @@
*/
public int getPriority(BluetoothDevice device) {
if (VDBG) Log.d(TAG, "getPriority(" + device + ")");
- if (mService != null && isEnabled() &&
- isValidDevice(device)) {
+ final IBluetoothMapClient service = mService;
+ if (service != null && isEnabled() && isValidDevice(device)) {
try {
- return mService.getPriority(device);
+ return service.getPriority(device);
} catch (RemoteException e) {
Log.e(TAG, Log.getStackTraceString(new Throwable()));
return PRIORITY_OFF;
}
}
- if (mService == null) Log.w(TAG, "Proxy not attached to service");
+ if (service == null) Log.w(TAG, "Proxy not attached to service");
return PRIORITY_OFF;
}
@@ -357,9 +361,10 @@
public boolean sendMessage(BluetoothDevice device, Uri[] contacts, String message,
PendingIntent sentIntent, PendingIntent deliveredIntent) {
if (DBG) Log.d(TAG, "sendMessage(" + device + ", " + contacts + ", " + message);
- if (mService != null && isEnabled() && isValidDevice(device)) {
+ final IBluetoothMapClient service = mService;
+ if (service != null && isEnabled() && isValidDevice(device)) {
try {
- return mService.sendMessage(device, contacts, message, sentIntent, deliveredIntent);
+ return service.sendMessage(device, contacts, message, sentIntent, deliveredIntent);
} catch (RemoteException e) {
Log.e(TAG, Log.getStackTraceString(new Throwable()));
return false;
@@ -376,9 +381,10 @@
*/
public boolean getUnreadMessages(BluetoothDevice device) {
if (DBG) Log.d(TAG, "getUnreadMessages(" + device + ")");
- if (mService != null && isEnabled() && isValidDevice(device)) {
+ final IBluetoothMapClient service = mService;
+ if (service != null && isEnabled() && isValidDevice(device)) {
try {
- return mService.getUnreadMessages(device);
+ return service.getUnreadMessages(device);
} catch (RemoteException e) {
Log.e(TAG, Log.getStackTraceString(new Throwable()));
return false;
@@ -413,12 +419,8 @@
return false;
}
- private boolean isValidDevice(BluetoothDevice device) {
- if (device == null) return false;
-
- if (BluetoothAdapter.checkBluetoothAddress(device.getAddress())) return true;
- return false;
+ private static boolean isValidDevice(BluetoothDevice device) {
+ return device != null && BluetoothAdapter.checkBluetoothAddress(device.getAddress());
}
-
}
diff --git a/core/java/android/bluetooth/BluetoothPan.java b/core/java/android/bluetooth/BluetoothPan.java
index 2a026a9..123d10b 100644
--- a/core/java/android/bluetooth/BluetoothPan.java
+++ b/core/java/android/bluetooth/BluetoothPan.java
@@ -121,7 +121,7 @@
private Context mContext;
private ServiceListener mServiceListener;
private BluetoothAdapter mAdapter;
- private IBluetoothPan mPanService;
+ private volatile IBluetoothPan mPanService;
/**
* Create a BluetoothPan proxy object for interacting with the local
@@ -235,16 +235,16 @@
*/
public boolean connect(BluetoothDevice device) {
if (DBG) log("connect(" + device + ")");
- if (mPanService != null && isEnabled() &&
- isValidDevice(device)) {
+ final IBluetoothPan service = mPanService;
+ if (service != null && isEnabled() && isValidDevice(device)) {
try {
- return mPanService.connect(device);
+ return service.connect(device);
} catch (RemoteException e) {
Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
return false;
}
}
- if (mPanService == null) Log.w(TAG, "Proxy not attached to service");
+ if (service == null) Log.w(TAG, "Proxy not attached to service");
return false;
}
@@ -276,16 +276,16 @@
*/
public boolean disconnect(BluetoothDevice device) {
if (DBG) log("disconnect(" + device + ")");
- if (mPanService != null && isEnabled() &&
- isValidDevice(device)) {
+ final IBluetoothPan service = mPanService;
+ if (service != null && isEnabled() && isValidDevice(device)) {
try {
- return mPanService.disconnect(device);
+ return service.disconnect(device);
} catch (RemoteException e) {
Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
return false;
}
}
- if (mPanService == null) Log.w(TAG, "Proxy not attached to service");
+ if (service == null) Log.w(TAG, "Proxy not attached to service");
return false;
}
@@ -294,15 +294,16 @@
*/
public List<BluetoothDevice> getConnectedDevices() {
if (VDBG) log("getConnectedDevices()");
- if (mPanService != null && isEnabled()) {
+ final IBluetoothPan service = mPanService;
+ if (service != null && isEnabled()) {
try {
- return mPanService.getConnectedDevices();
+ return service.getConnectedDevices();
} catch (RemoteException e) {
Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
return new ArrayList<BluetoothDevice>();
}
}
- if (mPanService == null) Log.w(TAG, "Proxy not attached to service");
+ if (service == null) Log.w(TAG, "Proxy not attached to service");
return new ArrayList<BluetoothDevice>();
}
@@ -311,15 +312,16 @@
*/
public List<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states) {
if (VDBG) log("getDevicesMatchingStates()");
- if (mPanService != null && isEnabled()) {
+ final IBluetoothPan service = mPanService;
+ if (service != null && isEnabled()) {
try {
- return mPanService.getDevicesMatchingConnectionStates(states);
+ return service.getDevicesMatchingConnectionStates(states);
} catch (RemoteException e) {
Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
return new ArrayList<BluetoothDevice>();
}
}
- if (mPanService == null) Log.w(TAG, "Proxy not attached to service");
+ if (service == null) Log.w(TAG, "Proxy not attached to service");
return new ArrayList<BluetoothDevice>();
}
@@ -328,25 +330,25 @@
*/
public int getConnectionState(BluetoothDevice device) {
if (VDBG) log("getState(" + device + ")");
- if (mPanService != null && isEnabled()
- && isValidDevice(device)) {
+ final IBluetoothPan service = mPanService;
+ if (service != null && isEnabled() && isValidDevice(device)) {
try {
- return mPanService.getConnectionState(device);
+ return service.getConnectionState(device);
} catch (RemoteException e) {
Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
return BluetoothProfile.STATE_DISCONNECTED;
}
}
- if (mPanService == null) Log.w(TAG, "Proxy not attached to service");
+ if (service == null) Log.w(TAG, "Proxy not attached to service");
return BluetoothProfile.STATE_DISCONNECTED;
}
public void setBluetoothTethering(boolean value) {
if (DBG) log("setBluetoothTethering(" + value + ")");
-
- if (mPanService != null && isEnabled()) {
+ final IBluetoothPan service = mPanService;
+ if (service != null && isEnabled()) {
try {
- mPanService.setBluetoothTethering(value);
+ service.setBluetoothTethering(value);
} catch (RemoteException e) {
Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
}
@@ -355,10 +357,10 @@
public boolean isTetheringOn() {
if (VDBG) log("isTetheringOn()");
-
- if (mPanService != null && isEnabled()) {
+ final IBluetoothPan service = mPanService;
+ if (service != null && isEnabled()) {
try {
- return mPanService.isTetheringOn();
+ return service.isTetheringOn();
} catch (RemoteException e) {
Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
}
@@ -370,7 +372,6 @@
public void onServiceConnected(ComponentName className, IBinder service) {
if (DBG) Log.d(TAG, "BluetoothPAN Proxy object connected");
mPanService = IBluetoothPan.Stub.asInterface(Binder.allowBlocking(service));
-
if (mServiceListener != null) {
mServiceListener.onServiceConnected(BluetoothProfile.PAN,
BluetoothPan.this);
@@ -386,15 +387,11 @@
};
private boolean isEnabled() {
- if (mAdapter.getState() == BluetoothAdapter.STATE_ON) return true;
- return false;
+ return mAdapter.getState() == BluetoothAdapter.STATE_ON;
}
- private boolean isValidDevice(BluetoothDevice device) {
- if (device == null) return false;
-
- if (BluetoothAdapter.checkBluetoothAddress(device.getAddress())) return true;
- return false;
+ private static boolean isValidDevice(BluetoothDevice device) {
+ return device != null && BluetoothAdapter.checkBluetoothAddress(device.getAddress());
}
private static void log(String msg) {
diff --git a/core/java/android/bluetooth/BluetoothPbap.java b/core/java/android/bluetooth/BluetoothPbap.java
index dc01fc7..f16160e4 100644
--- a/core/java/android/bluetooth/BluetoothPbap.java
+++ b/core/java/android/bluetooth/BluetoothPbap.java
@@ -20,8 +20,8 @@
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
-import android.os.RemoteException;
import android.os.IBinder;
+import android.os.RemoteException;
import android.util.Log;
/**
@@ -67,7 +67,7 @@
public static final String PBAP_STATE_CHANGED_ACTION =
"android.bluetooth.pbap.intent.action.PBAP_STATE_CHANGED";
- private IBluetoothPbap mService;
+ private volatile IBluetoothPbap mService;
private final Context mContext;
private ServiceListener mServiceListener;
private BluetoothAdapter mAdapter;
@@ -212,10 +212,13 @@
*/
public int getState() {
if (VDBG) log("getState()");
- if (mService != null) {
+ final IBluetoothPbap service = mService;
+ if (service != null) {
try {
- return mService.getState();
- } catch (RemoteException e) {Log.e(TAG, e.toString());}
+ return service.getState();
+ } catch (RemoteException e) {
+ Log.e(TAG, e.toString());
+ }
} else {
Log.w(TAG, "Proxy not attached to service");
if (DBG) log(Log.getStackTraceString(new Throwable()));
@@ -231,10 +234,13 @@
*/
public BluetoothDevice getClient() {
if (VDBG) log("getClient()");
- if (mService != null) {
+ final IBluetoothPbap service = mService;
+ if (service != null) {
try {
- return mService.getClient();
- } catch (RemoteException e) {Log.e(TAG, e.toString());}
+ return service.getClient();
+ } catch (RemoteException e) {
+ Log.e(TAG, e.toString());
+ }
} else {
Log.w(TAG, "Proxy not attached to service");
if (DBG) log(Log.getStackTraceString(new Throwable()));
@@ -249,10 +255,13 @@
*/
public boolean isConnected(BluetoothDevice device) {
if (VDBG) log("isConnected(" + device + ")");
- if (mService != null) {
+ final IBluetoothPbap service = mService;
+ if (service != null) {
try {
- return mService.isConnected(device);
- } catch (RemoteException e) {Log.e(TAG, e.toString());}
+ return service.isConnected(device);
+ } catch (RemoteException e) {
+ Log.e(TAG, e.toString());
+ }
} else {
Log.w(TAG, "Proxy not attached to service");
if (DBG) log(Log.getStackTraceString(new Throwable()));
@@ -267,9 +276,10 @@
*/
public boolean disconnect() {
if (DBG) log("disconnect()");
- if (mService != null) {
+ final IBluetoothPbap service = mService;
+ if (service != null) {
try {
- mService.disconnect();
+ service.disconnect();
return true;
} catch (RemoteException e) {Log.e(TAG, e.toString());}
} else {
diff --git a/core/java/android/bluetooth/BluetoothPbapClient.java b/core/java/android/bluetooth/BluetoothPbapClient.java
index 9f00e1a..28b551e 100644
--- a/core/java/android/bluetooth/BluetoothPbapClient.java
+++ b/core/java/android/bluetooth/BluetoothPbapClient.java
@@ -16,17 +16,18 @@
package android.bluetooth;
-import java.util.List;
-import java.util.ArrayList;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
-import android.os.RemoteException;
import android.os.Binder;
import android.os.IBinder;
+import android.os.RemoteException;
import android.util.Log;
+import java.util.ArrayList;
+import java.util.List;
+
/**
* This class provides the APIs to control the Bluetooth PBAP Client Profile.
*@hide
@@ -40,7 +41,7 @@
public static final String ACTION_CONNECTION_STATE_CHANGED =
"android.bluetooth.pbap.profile.action.CONNECTION_STATE_CHANGED";
- private IBluetoothPbapClient mService;
+ private volatile IBluetoothPbapClient mService;
private final Context mContext;
private ServiceListener mServiceListener;
private BluetoothAdapter mAdapter;
@@ -171,15 +172,16 @@
if (DBG) {
log("connect(" + device + ") for PBAP Client.");
}
- if (mService != null && isEnabled() && isValidDevice(device)) {
+ final IBluetoothPbapClient service = mService;
+ if (service != null && isEnabled() && isValidDevice(device)) {
try {
- return mService.connect(device);
+ return service.connect(device);
} catch (RemoteException e) {
Log.e(TAG, Log.getStackTraceString(new Throwable()));
return false;
}
}
- if (mService == null) {
+ if (service == null) {
Log.w(TAG, "Proxy not attached to service");
}
return false;
@@ -196,16 +198,17 @@
if (DBG) {
log("disconnect(" + device + ")" + new Exception() );
}
- if (mService != null && isEnabled() && isValidDevice(device)) {
+ final IBluetoothPbapClient service = mService;
+ if (service != null && isEnabled() && isValidDevice(device)) {
try {
- mService.disconnect(device);
+ service.disconnect(device);
return true;
} catch (RemoteException e) {
Log.e(TAG, Log.getStackTraceString(new Throwable()));
return false;
}
}
- if (mService == null) {
+ if (service == null) {
Log.w(TAG, "Proxy not attached to service");
}
return false;
@@ -222,15 +225,16 @@
if (DBG) {
log("getConnectedDevices()");
}
- if (mService != null && isEnabled()) {
+ final IBluetoothPbapClient service = mService;
+ if (service != null && isEnabled()) {
try {
- return mService.getConnectedDevices();
+ return service.getConnectedDevices();
} catch (RemoteException e) {
Log.e(TAG, Log.getStackTraceString(new Throwable()));
return new ArrayList<BluetoothDevice>();
}
}
- if (mService == null) {
+ if (service == null) {
Log.w(TAG, "Proxy not attached to service");
}
return new ArrayList<BluetoothDevice>();
@@ -246,15 +250,16 @@
if (DBG) {
log("getDevicesMatchingStates()");
}
- if (mService != null && isEnabled()) {
+ final IBluetoothPbapClient service = mService;
+ if (service != null && isEnabled()) {
try {
- return mService.getDevicesMatchingConnectionStates(states);
+ return service.getDevicesMatchingConnectionStates(states);
} catch (RemoteException e) {
Log.e(TAG, Log.getStackTraceString(new Throwable()));
return new ArrayList<BluetoothDevice>();
}
}
- if (mService == null) {
+ if (service == null) {
Log.w(TAG, "Proxy not attached to service");
}
return new ArrayList<BluetoothDevice>();
@@ -270,15 +275,16 @@
if (DBG) {
log("getConnectionState(" + device + ")");
}
- if (mService != null && isEnabled() && isValidDevice(device)) {
+ final IBluetoothPbapClient service = mService;
+ if (service != null && isEnabled() && isValidDevice(device)) {
try {
- return mService.getConnectionState(device);
+ return service.getConnectionState(device);
} catch (RemoteException e) {
Log.e(TAG, Log.getStackTraceString(new Throwable()));
return BluetoothProfile.STATE_DISCONNECTED;
}
}
- if (mService == null) {
+ if (service == null) {
Log.w(TAG, "Proxy not attached to service");
}
return BluetoothProfile.STATE_DISCONNECTED;
@@ -318,14 +324,8 @@
return false;
}
- private boolean isValidDevice(BluetoothDevice device) {
- if (device == null) {
- return false;
- }
- if (BluetoothAdapter.checkBluetoothAddress(device.getAddress())) {
- return true;
- }
- return false;
+ private static boolean isValidDevice(BluetoothDevice device) {
+ return device != null && BluetoothAdapter.checkBluetoothAddress(device.getAddress());
}
/**
@@ -336,27 +336,27 @@
* {@link #PRIORITY_OFF},
*
* @param device Paired bluetooth device
- * @param priority
+ * @param priority Priority of this profile
* @return true if priority is set, false on error
*/
public boolean setPriority(BluetoothDevice device, int priority) {
if (DBG) {
log("setPriority(" + device + ", " + priority + ")");
}
- if (mService != null && isEnabled() &&
- isValidDevice(device)) {
- if (priority != BluetoothProfile.PRIORITY_OFF &&
- priority != BluetoothProfile.PRIORITY_ON) {
- return false;
+ final IBluetoothPbapClient service = mService;
+ if (service != null && isEnabled() && isValidDevice(device)) {
+ if (priority != BluetoothProfile.PRIORITY_OFF
+ && priority != BluetoothProfile.PRIORITY_ON) {
+ return false;
}
try {
- return mService.setPriority(device, priority);
+ return service.setPriority(device, priority);
} catch (RemoteException e) {
Log.e(TAG, Log.getStackTraceString(new Throwable()));
return false;
}
}
- if (mService == null) {
+ if (service == null) {
Log.w(TAG, "Proxy not attached to service");
}
return false;
@@ -376,15 +376,16 @@
if (VDBG) {
log("getPriority(" + device + ")");
}
- if (mService != null && isEnabled() && isValidDevice(device)) {
+ final IBluetoothPbapClient service = mService;
+ if (service != null && isEnabled() && isValidDevice(device)) {
try {
- return mService.getPriority(device);
+ return service.getPriority(device);
} catch (RemoteException e) {
Log.e(TAG, Log.getStackTraceString(new Throwable()));
return PRIORITY_OFF;
}
}
- if (mService == null) {
+ if (service == null) {
Log.w(TAG, "Proxy not attached to service");
}
return PRIORITY_OFF;
diff --git a/core/java/android/bluetooth/BluetoothSap.java b/core/java/android/bluetooth/BluetoothSap.java
index 89c1bf8..f9ddb2e 100644
--- a/core/java/android/bluetooth/BluetoothSap.java
+++ b/core/java/android/bluetooth/BluetoothSap.java
@@ -16,19 +16,18 @@
package android.bluetooth;
-import java.util.ArrayList;
-import java.util.List;
-
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
-import android.os.RemoteException;
import android.os.Binder;
import android.os.IBinder;
-import android.os.ServiceManager;
+import android.os.RemoteException;
import android.util.Log;
+import java.util.ArrayList;
+import java.util.List;
+
/**
* This class provides the APIs to control the Bluetooth SIM
* Access Profile (SAP).
@@ -67,7 +66,7 @@
public static final String ACTION_CONNECTION_STATE_CHANGED =
"android.bluetooth.sap.profile.action.CONNECTION_STATE_CHANGED";
- private IBluetoothSap mService;
+ private volatile IBluetoothSap mService;
private final Context mContext;
private ServiceListener mServiceListener;
private BluetoothAdapter mAdapter;
@@ -196,10 +195,13 @@
*/
public int getState() {
if (VDBG) log("getState()");
- if (mService != null) {
+ final IBluetoothSap service = mService;
+ if (service != null) {
try {
- return mService.getState();
- } catch (RemoteException e) {Log.e(TAG, e.toString());}
+ return service.getState();
+ } catch (RemoteException e) {
+ Log.e(TAG, e.toString());
+ }
} else {
Log.w(TAG, "Proxy not attached to service");
if (DBG) log(Log.getStackTraceString(new Throwable()));
@@ -216,10 +218,13 @@
*/
public BluetoothDevice getClient() {
if (VDBG) log("getClient()");
- if (mService != null) {
+ final IBluetoothSap service = mService;
+ if (service != null) {
try {
- return mService.getClient();
- } catch (RemoteException e) {Log.e(TAG, e.toString());}
+ return service.getClient();
+ } catch (RemoteException e) {
+ Log.e(TAG, e.toString());
+ }
} else {
Log.w(TAG, "Proxy not attached to service");
if (DBG) log(Log.getStackTraceString(new Throwable()));
@@ -235,10 +240,13 @@
*/
public boolean isConnected(BluetoothDevice device) {
if (VDBG) log("isConnected(" + device + ")");
- if (mService != null) {
+ final IBluetoothSap service = mService;
+ if (service != null) {
try {
- return mService.isConnected(device);
- } catch (RemoteException e) {Log.e(TAG, e.toString());}
+ return service.isConnected(device);
+ } catch (RemoteException e) {
+ Log.e(TAG, e.toString());
+ }
} else {
Log.w(TAG, "Proxy not attached to service");
if (DBG) log(Log.getStackTraceString(new Throwable()));
@@ -266,16 +274,16 @@
*/
public boolean disconnect(BluetoothDevice device) {
if (DBG) log("disconnect(" + device + ")");
- if (mService != null && isEnabled() &&
- isValidDevice(device)) {
+ final IBluetoothSap service = mService;
+ if (service != null && isEnabled() && isValidDevice(device)) {
try {
- return mService.disconnect(device);
+ return service.disconnect(device);
} catch (RemoteException e) {
Log.e(TAG, Log.getStackTraceString(new Throwable()));
return false;
}
}
- if (mService == null) Log.w(TAG, "Proxy not attached to service");
+ if (service == null) Log.w(TAG, "Proxy not attached to service");
return false;
}
@@ -287,15 +295,16 @@
*/
public List<BluetoothDevice> getConnectedDevices() {
if (DBG) log("getConnectedDevices()");
- if (mService != null && isEnabled()) {
+ final IBluetoothSap service = mService;
+ if (service != null && isEnabled()) {
try {
- return mService.getConnectedDevices();
+ return service.getConnectedDevices();
} catch (RemoteException e) {
Log.e(TAG, Log.getStackTraceString(new Throwable()));
return new ArrayList<BluetoothDevice>();
}
}
- if (mService == null) Log.w(TAG, "Proxy not attached to service");
+ if (service == null) Log.w(TAG, "Proxy not attached to service");
return new ArrayList<BluetoothDevice>();
}
@@ -307,15 +316,16 @@
*/
public List<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states) {
if (DBG) log("getDevicesMatchingStates()");
- if (mService != null && isEnabled()) {
+ final IBluetoothSap service = mService;
+ if (service != null && isEnabled()) {
try {
- return mService.getDevicesMatchingConnectionStates(states);
+ return service.getDevicesMatchingConnectionStates(states);
} catch (RemoteException e) {
Log.e(TAG, Log.getStackTraceString(new Throwable()));
return new ArrayList<BluetoothDevice>();
}
}
- if (mService == null) Log.w(TAG, "Proxy not attached to service");
+ if (service == null) Log.w(TAG, "Proxy not attached to service");
return new ArrayList<BluetoothDevice>();
}
@@ -327,16 +337,16 @@
*/
public int getConnectionState(BluetoothDevice device) {
if (DBG) log("getConnectionState(" + device + ")");
- if (mService != null && isEnabled() &&
- isValidDevice(device)) {
+ final IBluetoothSap service = mService;
+ if (service != null && isEnabled() && isValidDevice(device)) {
try {
- return mService.getConnectionState(device);
+ return service.getConnectionState(device);
} catch (RemoteException e) {
Log.e(TAG, Log.getStackTraceString(new Throwable()));
return BluetoothProfile.STATE_DISCONNECTED;
}
}
- if (mService == null) Log.w(TAG, "Proxy not attached to service");
+ if (service == null) Log.w(TAG, "Proxy not attached to service");
return BluetoothProfile.STATE_DISCONNECTED;
}
@@ -352,20 +362,20 @@
*/
public boolean setPriority(BluetoothDevice device, int priority) {
if (DBG) log("setPriority(" + device + ", " + priority + ")");
- if (mService != null && isEnabled() &&
- isValidDevice(device)) {
- if (priority != BluetoothProfile.PRIORITY_OFF &&
- priority != BluetoothProfile.PRIORITY_ON) {
- return false;
+ final IBluetoothSap service = mService;
+ if (service != null && isEnabled() && isValidDevice(device)) {
+ if (priority != BluetoothProfile.PRIORITY_OFF
+ && priority != BluetoothProfile.PRIORITY_ON) {
+ return false;
}
try {
- return mService.setPriority(device, priority);
+ return service.setPriority(device, priority);
} catch (RemoteException e) {
Log.e(TAG, Log.getStackTraceString(new Throwable()));
return false;
}
}
- if (mService == null) Log.w(TAG, "Proxy not attached to service");
+ if (service == null) Log.w(TAG, "Proxy not attached to service");
return false;
}
@@ -378,20 +388,20 @@
*/
public int getPriority(BluetoothDevice device) {
if (VDBG) log("getPriority(" + device + ")");
- if (mService != null && isEnabled() &&
- isValidDevice(device)) {
+ final IBluetoothSap service = mService;
+ if (service != null && isEnabled() && isValidDevice(device)) {
try {
- return mService.getPriority(device);
+ return service.getPriority(device);
} catch (RemoteException e) {
Log.e(TAG, Log.getStackTraceString(new Throwable()));
return PRIORITY_OFF;
}
}
- if (mService == null) Log.w(TAG, "Proxy not attached to service");
+ if (service == null) Log.w(TAG, "Proxy not attached to service");
return PRIORITY_OFF;
}
- private ServiceConnection mConnection = new ServiceConnection() {
+ private final ServiceConnection mConnection = new ServiceConnection() {
public void onServiceConnected(ComponentName className, IBinder service) {
if (DBG) log("Proxy object connected");
mService = IBluetoothSap.Stub.asInterface(Binder.allowBlocking(service));
@@ -421,13 +431,8 @@
return false;
}
- private boolean isValidDevice(BluetoothDevice device) {
- if (device == null)
- return false;
-
- if (BluetoothAdapter.checkBluetoothAddress(device.getAddress()))
- return true;
- return false;
+ private static boolean isValidDevice(BluetoothDevice device) {
+ return device != null && BluetoothAdapter.checkBluetoothAddress(device.getAddress());
}
}
diff --git a/core/java/android/bluetooth/le/BluetoothLeScanner.java b/core/java/android/bluetooth/le/BluetoothLeScanner.java
index 9e9c8fe..7106a84 100644
--- a/core/java/android/bluetooth/le/BluetoothLeScanner.java
+++ b/core/java/android/bluetooth/le/BluetoothLeScanner.java
@@ -137,6 +137,11 @@
* the PendingIntent. Use this method of scanning if your process is not always running and it
* should be started when scan results are available.
* <p>
+ * An app must hold
+ * {@link android.Manifest.permission#ACCESS_COARSE_LOCATION ACCESS_COARSE_LOCATION} or
+ * {@link android.Manifest.permission#ACCESS_FINE_LOCATION ACCESS_FINE_LOCATION} permission
+ * in order to get results.
+ * <p>
* When the PendingIntent is delivered, the Intent passed to the receiver or activity
* will contain one or more of the extras {@link #EXTRA_CALLBACK_TYPE},
* {@link #EXTRA_ERROR_CODE} and {@link #EXTRA_LIST_SCAN_RESULT} to indicate the result of
diff --git a/core/java/android/database/sqlite/SQLiteGlobal.java b/core/java/android/database/sqlite/SQLiteGlobal.java
index 571656a..94d5555 100644
--- a/core/java/android/database/sqlite/SQLiteGlobal.java
+++ b/core/java/android/database/sqlite/SQLiteGlobal.java
@@ -16,6 +16,7 @@
package android.database.sqlite;
+import android.annotation.TestApi;
import android.content.res.Resources;
import android.os.StatFs;
import android.os.SystemProperties;
@@ -34,6 +35,7 @@
*
* @hide
*/
+@TestApi
public final class SQLiteGlobal {
private static final String TAG = "SQLiteGlobal";
diff --git a/core/java/android/net/LinkProperties.java b/core/java/android/net/LinkProperties.java
index 1bb0fbb..f527f77 100644
--- a/core/java/android/net/LinkProperties.java
+++ b/core/java/android/net/LinkProperties.java
@@ -18,14 +18,13 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
-import android.net.ProxyInfo;
-import android.os.Parcelable;
import android.os.Parcel;
+import android.os.Parcelable;
import android.text.TextUtils;
-import java.net.InetAddress;
import java.net.Inet4Address;
import java.net.Inet6Address;
+import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.Collection;
@@ -504,11 +503,22 @@
}
/**
+ * Make sure this LinkProperties instance contains routes that cover the local subnet
+ * of its link addresses. Add any route that is missing.
+ * @hide
+ */
+ public void ensureDirectlyConnectedRoutes() {
+ for (LinkAddress addr: mLinkAddresses) {
+ addRoute(new RouteInfo(addr, null, mIfaceName));
+ }
+ }
+
+ /**
* Returns all the routes on this link and all the links stacked above it.
* @hide
*/
public List<RouteInfo> getAllRoutes() {
- List<RouteInfo> routes = new ArrayList();
+ List<RouteInfo> routes = new ArrayList<>();
routes.addAll(mRoutes);
for (LinkProperties stacked: mStackedLinks.values()) {
routes.addAll(stacked.getAllRoutes());
diff --git a/core/java/android/service/autofill/CharSequenceTransformation.java b/core/java/android/service/autofill/CharSequenceTransformation.java
index 8ab856e..2413e97 100644
--- a/core/java/android/service/autofill/CharSequenceTransformation.java
+++ b/core/java/android/service/autofill/CharSequenceTransformation.java
@@ -86,7 +86,7 @@
}
try {
final Matcher matcher = field.first.matcher(value);
- if (!matcher.matches()) {
+ if (!matcher.find()) {
if (sDebug) Log.d(TAG, "match for " + field.first + " failed on id " + id);
return;
}
diff --git a/core/java/android/service/autofill/FillResponse.java b/core/java/android/service/autofill/FillResponse.java
index 3b09c67..6d8a959 100644
--- a/core/java/android/service/autofill/FillResponse.java
+++ b/core/java/android/service/autofill/FillResponse.java
@@ -148,10 +148,12 @@
* {@link android.view.autofill.AutofillManager#EXTRA_ASSIST_STRUCTURE screen
* content} and your {@link android.view.autofill.AutofillManager#EXTRA_CLIENT_STATE
* client state}. Once you complete your authentication flow you should set the
- * {@link Activity} result to {@link android.app.Activity#RESULT_OK} and provide the fully
- * populated {@link FillResponse response} by setting it to the
- * {@link android.view.autofill.AutofillManager#EXTRA_AUTHENTICATION_RESULT} extra.
- * For example, if you provided an empty {@link FillResponse resppnse} because the
+ * {@link Activity} result to {@link android.app.Activity#RESULT_OK} and set the
+ * {@link android.view.autofill.AutofillManager#EXTRA_AUTHENTICATION_RESULT} extra
+ * with the fully populated {@link FillResponse response} (or {@code null} if the screen
+ * cannot be autofilled).
+ *
+ * <p>For example, if you provided an empty {@link FillResponse response} because the
* user's data was locked and marked that the response needs an authentication then
* in the response returned if authentication succeeds you need to provide all
* available data sets some of which may need to be further authenticated, for
diff --git a/core/java/android/service/oemlock/IOemLockService.aidl b/core/java/android/service/oemlock/IOemLockService.aidl
index 682e7ee..d5e10d6 100644
--- a/core/java/android/service/oemlock/IOemLockService.aidl
+++ b/core/java/android/service/oemlock/IOemLockService.aidl
@@ -28,7 +28,6 @@
void setOemUnlockAllowedByUser(boolean allowed);
boolean isOemUnlockAllowedByUser();
- boolean canUserAllowOemUnlock();
boolean isOemUnlockAllowed();
boolean isDeviceOemUnlocked();
}
diff --git a/core/java/android/service/oemlock/OemLockManager.java b/core/java/android/service/oemlock/OemLockManager.java
index 3a56d9f..f0d6603 100644
--- a/core/java/android/service/oemlock/OemLockManager.java
+++ b/core/java/android/service/oemlock/OemLockManager.java
@@ -118,24 +118,6 @@
}
/**
- * Returns whether all parties other than the user allow OEM unlock meaning the user can
- * directly control whether or not the device can be OEM unlocked.
- *
- * If this is true, {@link #isOemUnlockAllowedByUser} is the same as {@link #isOemUnlockAllowed}
- *
- * @return Whether the user can directly control whether the device can be OEM unlocked.
- *
- * @hide
- */
- public boolean canUserAllowOemUnlock() {
- try {
- return mService.canUserAllowOemUnlock();
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /**
* @return Whether the bootloader is able to OEM unlock the device.
*
* @hide
diff --git a/core/java/android/view/KeyEvent.java b/core/java/android/view/KeyEvent.java
index 829b2b7..a2147b7 100644
--- a/core/java/android/view/KeyEvent.java
+++ b/core/java/android/view/KeyEvent.java
@@ -804,8 +804,11 @@
public static final int KEYCODE_SYSTEM_NAVIGATION_LEFT = 282;
/** Key code constant: Consumed by the system for navigation right */
public static final int KEYCODE_SYSTEM_NAVIGATION_RIGHT = 283;
+ /** Key code constant: Show all apps
+ * @hide */
+ public static final int KEYCODE_ALL_APPS = 284;
- private static final int LAST_KEYCODE = KEYCODE_SYSTEM_NAVIGATION_RIGHT;
+ private static final int LAST_KEYCODE = KEYCODE_ALL_APPS;
// NOTE: If you add a new keycode here you must also add it to:
// isSystem()
diff --git a/core/java/com/android/internal/app/PlatLogoActivity.java b/core/java/com/android/internal/app/PlatLogoActivity.java
index 36ab394..b22ce5e 100644
--- a/core/java/com/android/internal/app/PlatLogoActivity.java
+++ b/core/java/com/android/internal/app/PlatLogoActivity.java
@@ -53,8 +53,7 @@
import android.widget.ImageView;
public class PlatLogoActivity extends Activity {
- public static final boolean REVEAL_THE_NAME = false;
- public static final boolean FINISH = false;
+ public static final boolean FINISH = true;
FrameLayout mLayout;
int mTapCount;
@@ -85,15 +84,18 @@
im.setAlpha(0f);
im.setBackground(new RippleDrawable(
- ColorStateList.valueOf(0xFFFFFFFF),
+ ColorStateList.valueOf(0xFF776677),
getDrawable(com.android.internal.R.drawable.platlogo),
null));
-// im.setOutlineProvider(new ViewOutlineProvider() {
-// @Override
-// public void getOutline(View view, Outline outline) {
-// outline.setOval(0, 0, view.getWidth(), view.getHeight());
-// }
-// });
+ im.setOutlineProvider(new ViewOutlineProvider() {
+ @Override
+ public void getOutline(View view, Outline outline) {
+ final int w = view.getWidth();
+ final int h = view.getHeight();
+ outline.setOval((int)(w*.125), (int)(h*.125), (int)(w*.96), (int)(h*.96));
+ }
+ });
+ im.setElevation(12f*dp);
im.setClickable(true);
im.setOnClickListener(new View.OnClickListener() {
@Override
@@ -103,18 +105,6 @@
public boolean onLongClick(View v) {
if (mTapCount < 5) return false;
- if (REVEAL_THE_NAME) {
- final Drawable overlay = getDrawable(
- com.android.internal.R.drawable.platlogo_m);
- overlay.setBounds(0, 0, v.getMeasuredWidth(), v.getMeasuredHeight());
- im.getOverlay().clear();
- im.getOverlay().add(overlay);
- overlay.setAlpha(0);
- ObjectAnimator.ofInt(overlay, "alpha", 0, 255)
- .setDuration(500)
- .start();
- }
-
final ContentResolver cr = getContentResolver();
if (Settings.System.getLong(cr, Settings.System.EGG_MODE, 0)
== 0) {
diff --git a/core/java/com/android/internal/policy/DecorView.java b/core/java/com/android/internal/policy/DecorView.java
index 0d962eb..4e06577 100644
--- a/core/java/com/android/internal/policy/DecorView.java
+++ b/core/java/com/android/internal/policy/DecorView.java
@@ -17,6 +17,9 @@
package com.android.internal.policy;
import android.graphics.Outline;
+import android.graphics.drawable.InsetDrawable;
+import android.graphics.drawable.LayerDrawable;
+import android.util.Pair;
import android.view.ViewOutlineProvider;
import android.view.accessibility.AccessibilityNodeInfo;
import com.android.internal.R;
@@ -1061,7 +1064,7 @@
WindowManager.LayoutParams attrs = mWindow.getAttributes();
int sysUiVisibility = attrs.systemUiVisibility | getWindowSystemUiVisibility();
- if (!mWindow.mIsFloating && ActivityManager.isHighEndGfx()) {
+ if (!mWindow.mIsFloating) {
boolean disallowAnimate = !isLaidOut();
disallowAnimate |= ((mLastWindowFlags ^ attrs.flags)
& FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS) != 0;
@@ -1103,8 +1106,8 @@
boolean navBarToLeftEdge = isNavBarToLeftEdge(mLastBottomInset, mLastLeftInset);
int navBarSize = getNavBarSize(mLastBottomInset, mLastRightInset, mLastLeftInset);
updateColorViewInt(mNavigationColorViewState, sysUiVisibility,
- mWindow.mNavigationBarColor, navBarSize, navBarToRightEdge || navBarToLeftEdge,
- navBarToLeftEdge,
+ mWindow.mNavigationBarColor, mWindow.mNavigationBarDividerColor, navBarSize,
+ navBarToRightEdge || navBarToLeftEdge, navBarToLeftEdge,
0 /* sideInset */, animate && !disallowAnimate, false /* force */);
boolean statusBarNeedsRightInset = navBarToRightEdge
@@ -1114,7 +1117,7 @@
int statusBarSideInset = statusBarNeedsRightInset ? mLastRightInset
: statusBarNeedsLeftInset ? mLastLeftInset : 0;
updateColorViewInt(mStatusColorViewState, sysUiVisibility,
- calculateStatusBarColor(), mLastTopInset,
+ calculateStatusBarColor(), 0, mLastTopInset,
false /* matchVertical */, statusBarNeedsLeftInset, statusBarSideInset,
animate && !disallowAnimate,
mForceWindowDrawsStatusBarBackground);
@@ -1201,6 +1204,7 @@
* @param state the color view to update.
* @param sysUiVis the current systemUiVisibility to apply.
* @param color the current color to apply.
+ * @param dividerColor the current divider color to apply.
* @param size the current size in the non-parent-matching dimension.
* @param verticalBar if true the view is attached to a vertical edge, otherwise to a
* horizontal edge,
@@ -1208,7 +1212,7 @@
* @param animate if true, the change will be animated.
*/
private void updateColorViewInt(final ColorViewState state, int sysUiVis, int color,
- int size, boolean verticalBar, boolean seascape, int sideMargin,
+ int dividerColor, int size, boolean verticalBar, boolean seascape, int sideMargin,
boolean animate, boolean force) {
state.present = state.attributes.isPresent(sysUiVis, mWindow.getAttributes().flags, force);
boolean show = state.attributes.isVisible(state.present, color,
@@ -1227,7 +1231,7 @@
if (view == null) {
if (showView) {
state.view = view = new View(mContext);
- view.setBackgroundColor(color);
+ setColor(view, color, dividerColor, verticalBar, seascape);
view.setTransitionName(state.attributes.transitionName);
view.setId(state.attributes.id);
visibilityChanged = true;
@@ -1262,7 +1266,7 @@
view.setLayoutParams(lp);
}
if (showView) {
- view.setBackgroundColor(color);
+ setColor(view, color, dividerColor, verticalBar, seascape);
}
}
if (visibilityChanged) {
@@ -1295,6 +1299,34 @@
state.color = color;
}
+ private static void setColor(View v, int color, int dividerColor, boolean verticalBar,
+ boolean seascape) {
+ if (dividerColor != 0) {
+ final Pair<Boolean, Boolean> dir = (Pair<Boolean, Boolean>) v.getTag();
+ if (dir == null || dir.first != verticalBar || dir.second != seascape) {
+ final int size = Math.round(
+ TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 1,
+ v.getContext().getResources().getDisplayMetrics()));
+ // Use an inset to make the divider line on the side that faces the app.
+ final InsetDrawable d = new InsetDrawable(new ColorDrawable(color),
+ verticalBar && !seascape ? size : 0,
+ !verticalBar ? size : 0,
+ verticalBar && seascape ? size : 0, 0);
+ v.setBackground(new LayerDrawable(new Drawable[] {
+ new ColorDrawable(dividerColor), d }));
+ v.setTag(new Pair<>(verticalBar, seascape));
+ } else {
+ final LayerDrawable d = (LayerDrawable) v.getBackground();
+ final InsetDrawable inset = ((InsetDrawable) d.getDrawable(1));
+ ((ColorDrawable) inset.getDrawable()).setColor(color);
+ ((ColorDrawable) d.getDrawable(0)).setColor(dividerColor);
+ }
+ } else {
+ v.setTag(null);
+ v.setBackgroundColor(color);
+ }
+ }
+
private void updateColorViewTranslations() {
// Put the color views back in place when they get moved off the screen
// due to the the ViewRootImpl panning.
diff --git a/core/java/com/android/internal/policy/PhoneWindow.java b/core/java/com/android/internal/policy/PhoneWindow.java
index 544afd9..5f1932c 100644
--- a/core/java/com/android/internal/policy/PhoneWindow.java
+++ b/core/java/com/android/internal/policy/PhoneWindow.java
@@ -233,6 +233,7 @@
private int mTextColor = 0;
int mStatusBarColor = 0;
int mNavigationBarColor = 0;
+ int mNavigationBarDividerColor = 0;
private boolean mForcedStatusBarColor = false;
private boolean mForcedNavigationBarColor = false;
@@ -2432,13 +2433,15 @@
}
if (!mForcedNavigationBarColor) {
mNavigationBarColor = a.getColor(R.styleable.Window_navigationBarColor, 0xFF000000);
+ mNavigationBarDividerColor = a.getColor(R.styleable.Window_navigationBarDividerColor,
+ 0x00000000);
}
WindowManager.LayoutParams params = getAttributes();
// Non-floating windows on high end devices must put up decor beneath the system bars and
// therefore must know about visibility changes of those.
- if (!mIsFloating && ActivityManager.isHighEndGfx()) {
+ if (!mIsFloating) {
if (!targetPreL && a.getBoolean(
R.styleable.Window_windowDrawsSystemBarBackgrounds,
false)) {
diff --git a/core/java/com/android/internal/widget/NotificationExpandButton.java b/core/java/com/android/internal/widget/NotificationExpandButton.java
index b702898..39f82a5 100644
--- a/core/java/com/android/internal/widget/NotificationExpandButton.java
+++ b/core/java/com/android/internal/widget/NotificationExpandButton.java
@@ -31,7 +31,6 @@
*/
@RemoteViews.RemoteView
public class NotificationExpandButton extends ImageView {
- private View mLabeledBy;
public NotificationExpandButton(Context context) {
super(context);
@@ -69,12 +68,5 @@
public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
super.onInitializeAccessibilityNodeInfo(info);
info.setClassName(Button.class.getName());
- if (mLabeledBy != null) {
- info.setLabeledBy(mLabeledBy);
- }
- }
-
- public void setLabeledBy(View labeledBy) {
- mLabeledBy = labeledBy;
}
}
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 89bbec2..031c3f5 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -309,6 +309,10 @@
<protected-broadcast android:name="com.android.server.usb.ACTION_OPEN_IN_APPS" />
<protected-broadcast android:name="com.android.server.am.DELETE_DUMPHEAP" />
<protected-broadcast android:name="com.android.server.net.action.SNOOZE_WARNING" />
+ <protected-broadcast android:name="com.android.server.wifi.ConnectToNetworkNotification.USER_DISMISSED_NOTIFICATION" />
+ <protected-broadcast android:name="com.android.server.wifi.ConnectToNetworkNotification.CONNECT_TO_NETWORK" />
+ <protected-broadcast android:name="com.android.server.wifi.ConnectToNetworkNotification.PICK_WIFI_NETWORK" />
+ <protected-broadcast android:name="com.android.server.wifi.ConnectToNetworkNotification.PICK_NETWORK_AFTER_FAILURE" />
<protected-broadcast android:name="android.net.wifi.WIFI_STATE_CHANGED" />
<protected-broadcast android:name="android.net.wifi.WIFI_AP_STATE_CHANGED" />
<protected-broadcast android:name="android.net.wifi.WIFI_CREDENTIAL_CHANGED" />
diff --git a/core/res/res/drawable-nodpi/platlogo.xml b/core/res/res/drawable-nodpi/platlogo.xml
index 182ba24..a6dee8a 100644
--- a/core/res/res/drawable-nodpi/platlogo.xml
+++ b/core/res/res/drawable-nodpi/platlogo.xml
@@ -1,3 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (C) 2017 The Android Open Source Project
@@ -14,27 +15,35 @@
limitations under the License.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="480dp"
- android:height="480dp"
- android:viewportWidth="48.0"
- android:viewportHeight="48.0">
- <path
- android:pathData="M25.0,25.0m-20.5,0.0a20.5,20.5,0,1,1,41.0,0.0a20.5,20.5,0,1,1,-41.0,0.0"
- android:fillAlpha="0.066"
- android:fillColor="#000000"/>
- <path
- android:pathData="M24.0,24.0m-20.0,0.0a20.0,20.0,0,1,1,40.0,0.0a20.0,20.0,0,1,1,-40.0,0.0"
- android:fillColor="#FFC107"/>
- <path
- android:pathData="M44,24.2010101 L33.9004889,14.101499 L14.101499,33.9004889 L24.2010101,44 C29.2525804,43.9497929 34.2887564,41.9975027 38.1431296,38.1431296 C41.9975027,34.2887564 43.9497929,29.2525804 44,24.2010101 Z"
- android:fillColor="#FE9F00"/>
- <path
- android:pathData="M24.0,24.0m-14.0,0.0a14.0,14.0,0,1,1,28.0,0.0a14.0,14.0,0,1,1,-28.0,0.0"
- android:fillColor="#FED44F"/>
- <path
- android:pathData="M37.7829445,26.469236 L29.6578482,18.3441397 L18.3441397,29.6578482 L26.469236,37.7829445 C29.1911841,37.2979273 31.7972024,36.0037754 33.9004889,33.9004889 C36.0037754,31.7972024 37.2979273,29.1911841 37.7829445,26.469236 Z"
- android:fillColor="#FFC107"/>
- <path
- android:pathData="M24.0,24.0m-8.0,0.0a8.0,8.0,0,1,1,16.0,0.0a8.0,8.0,0,1,1,-16.0,0.0"
- android:fillColor="#FFFFFF"/>
+ android:width="48dp"
+ android:height="48dp"
+ android:viewportWidth="48"
+ android:viewportHeight="48">
+ <group>
+ <path
+ android:fillColor="#2C292A"
+ android:fillType="evenOdd"
+ android:pathData="M6,26a20,20 0 0,1 40,0a20,20 0 0,1 -40,0z"/>
+ <path
+ android:fillColor="#FAFAFA"
+ android:fillType="evenOdd"
+ android:pathData="M4,24a20,20 0 0,1 40,0a20,20 0 0,1 -40,0z"/>
+ <path
+ android:fillColor="#2C292A"
+ android:fillType="evenOdd"
+ android:pathData="M2,22a20,20 0 0,1 40,0a20,20 0 0,1 -40,0z"/>
+ <path
+ android:fillColor="#00000000"
+ android:strokeColor="#453F41"
+ android:strokeWidth="1"
+ android:fillType="evenOdd"
+ android:pathData="M26.5 29.5v3c0 1.13-.87 2-2 2s-2-.87-2-2v-3h-1v3c0 1.13-.87 2-2 2s-2-.87-2-2v-3H17a1.5 1.5 0 0 1-1.5-1.5V17.5h13V28a1.5 1.5 0 0 1-1.5 1.5h-.5zM13.5 17.5c1.13 0 2 .87 2 2v7c0 1.13-.87 2-2 2s-2-.87-2-2v-7c0-1.13.87-2 2-2zM30.5 17.5c1.13 0 2 .87 2 2v7c0 1.13-.87 2-2 2s-2-.87-2-2v-7c0-1.13.87-2 2-2zM26.3 12.11A6.46 6.46 0 0 1 28.5 17v.5h-13V17a6.46 6.46 0 0 1 2.2-4.89l-.9-.9a.98.98 0 0 1 0-1.41.98.98 0 0 1 1.4 0l1.26 1.25A6.33 6.33 0 0 1 22 10.5c.87 0 1.73.2 2.54.55L25.8 9.8a.98.98 0 0 1 1.4 0 .98.98 0 0 1 0 1.4l-.9.91z"/>
+ <path
+ android:fillColor="#453F41"
+ android:fillType="evenOdd"
+ android:pathData="M20.16 14.5a.66.66 0 1 1-1.31 0c0-.36.29-.65.65-.65.36 0 .65.29.65.65zM25.16 14.5c0 .36-.3.66-.66.66a.65.65 0 1 1 .66-.66z"/>
+ <path
+ android:fillColor="#453F41"
+ android:pathData="M22 40.5c0.36 0 0.73-0.01 1.09-0.03l-0.18-3A15.77 15.77 0 0 1 22 37.5v3zm2.17-0.13a18.48 18.48 0 0 0 1.08-0.15l-0.53-2.96c-0.3 0.05-0.6 0.1-0.9 0.13l0.35 2.98zM26.32 40a18.37 18.37 0 0 0 1.05-0.28l-0.87-2.87a15.37 15.37 0 0 1-0.88 0.23l0.7 2.92zm2.1-0.64l-1.03-2.81a15.39 15.39 0 0 0 0.84-0.34l1.2 2.74a18.39 18.39 0 0 1-1 0.41zm1.99-0.87l-1.37-2.67a15.46 15.46 0 0 0 0.8-0.44l1.52 2.59a18.46 18.46 0 0 1-0.95 0.52zm1.89-1.11l-1.67-2.5a15.55 15.55 0 0 0 0.74-0.52l1.81 2.39a18.55 18.55 0 0 1-0.88 0.63zm1.75-1.33l-1.95-2.28a15.6 15.6 0 0 0 0.67-0.61l2.09 2.15a18.6 18.6 0 0 1-0.8 0.74zm1.6-1.55l-2.22-2.02a15.6 15.6 0 0 0 0.6-0.7l2.33 1.9a18.6 18.6 0 0 1-0.72 0.82zM37 32.82l-2.43-1.76a15.53 15.53 0 0 0 0.5-0.75l2.54 1.6c-0.2 0.31-0.4 0.61-0.61 0.9zm1.15-1.8l-2.62-1.47a15.45 15.45 0 0 0 0.42-0.8l2.7 1.3a18.45 18.45 0 0 1-0.5 0.97zm0.95-1.98l-2.77-1.14a15.38 15.38 0 0 0 0.32-0.86l2.84 0.98a18.38 18.38 0 0 1-0.39 1.02zm0.72-2.09c0.1-0.34 0.18-0.7 0.26-1.05l-2.93-0.63a15.38 15.38 0 0 1-0.22 0.88l2.89 0.8zm0.46-2.15a18.52 18.52 0 0 0 0.13-1.08l-2.99-0.28a15.52 15.52 0 0 1-0.1 0.9l2.96 0.46zm0.2-2.2a18.81 18.81 0 0 0 0-1.1l-3 0.08a16 16 0 0 1 0 0.92l3 0.1zm-0.06-2.2a18.54 18.54 0 0 0-0.12-1.07l-2.97 0.43c0.04 0.3 0.08 0.6 0.1 0.9l3-0.25zm-0.31-2.15a18.39 18.39 0 0 0-0.25-1.06l-2.9 0.78a15.39 15.39 0 0 1 0.21 0.89l2.94-0.6zm-0.57-2.12l-2.85 0.95a15.37 15.37 0 0 0-0.31-0.85l2.78-1.12a18.37 18.37 0 0 1 0.38 1.02zm-0.83-2.06l-2.71 1.29a15.44 15.44 0 0 0-0.42-0.81l2.63-1.45a18.44 18.44 0 0 1 0.5 0.97zm-1.03-1.88l-2.54 1.6a15.53 15.53 0 0 0-0.5-0.76l2.44-1.74 0.6 0.9zm-1.28-1.79l-2.33 1.88a15.6 15.6 0 0 0-0.6-0.69l2.23-2.02a18.6 18.6 0 0 1 0.7 0.83zm-1.48-1.63l-2.1 2.14a15.6 15.6 0 0 0-0.67-0.62l1.97-2.26a18.6 18.6 0 0 1 0.8 0.74zM33.24 7.3l-1.82 2.38a15.55 15.55 0 0 0-0.74-0.53l1.68-2.49c0.3 0.2 0.6 0.42 0.88 0.64zm-1.71-1.17L29.98 8.7a15.47 15.47 0 0 0-0.8-0.45l1.4-2.66a18.47 18.47 0 0 1 0.95 0.54zm-1.95-1.02l-1.23 2.74A15.4 15.4 0 0 0 27.5 7.5l1.06-2.8a18.4 18.4 0 0 1 1.01 0.4zm-2.06-0.78l-0.9 2.86a15.37 15.37 0 0 0-0.87-0.24l0.72-2.92a18.37 18.37 0 0 1 1.05 0.3zM25.38 3.8a18.47 18.47 0 0 0-1.08-0.17l-0.37 2.98c0.3 0.04 0.6 0.08 0.9 0.14l0.55-2.95zm-2.2-0.27A18.75 18.75 0 0 0 22.1 3.5l-0.02 3L23 6.53l0.19-3zM21 3.53a18.6 18.6 0 0 0-1.08 0.09l0.33 2.98a15.6 15.6 0 0 1 0.91-0.08l-0.16-3zm-2.16 0.24A18.4 18.4 0 0 0 17.76 4l0.68 2.92a15.4 15.4 0 0 1 0.9-0.18l-0.51-2.96zm-2.14 0.5l0.86 2.88a15.37 15.37 0 0 0-0.86 0.28l-1.03-2.81a18.37 18.37 0 0 1 1.03-0.35zm-2.07 0.76l1.2 2.75a15.42 15.42 0 0 0-0.83 0.4L13.63 5.5a18.42 18.42 0 0 1 0.99-0.47zM12.7 6l1.5 2.6a15.5 15.5 0 0 0-0.76 0.48l-1.66-2.5A18.5 18.5 0 0 1 12.7 6zm-1.83 1.22l1.8 2.4a15.58 15.58 0 0 0-0.7 0.57L10.01 7.9a18.58 18.58 0 0 1 0.85-0.68zM9.19 8.66l2.07 2.16a15.6 15.6 0 0 0-0.63 0.65l-2.2-2.04a18.6 18.6 0 0 1 0.76-0.77zm-1.51 1.63l2.32 1.9a15.57 15.57 0 0 0-0.56 0.72l-2.42-1.76a18.57 18.57 0 0 1 0.66-0.86zm-1.23 1.69l2.52 1.62a15.5 15.5 0 0 0-0.47 0.78l-2.61-1.47a18.5 18.5 0 0 1 0.56-0.93zm-1.08 1.9l2.7 1.32a15.41 15.41 0 0 0-0.38 0.83l-2.77-1.15a18.41 18.41 0 0 1 0.45-1zm-0.85 2.04l2.84 0.98a15.37 15.37 0 0 0-0.28 0.87L4.2 16.96c0.1-0.35 0.2-0.7 0.32-1.04zm-0.6 2.12a18.43 18.43 0 0 0-0.2 1.07l2.97 0.47c0.05-0.3 0.1-0.6 0.17-0.9l-2.93-0.64zm-0.34 2.18a18.65 18.65 0 0 0-0.07 1.09l3 0.11 0.06-0.91-2.99-0.29zm-0.08 2.2a18.7 18.7 0 0 0 0.06 1.1l3-0.25a15.7 15.7 0 0 1-0.06-0.91l-3 0.07zm0.18 2.18a18.44 18.44 0 0 0 0.18 1.07l2.95-0.6a15.44 15.44 0 0 1-0.16-0.9L3.68 24.6zm0.43 2.14l2.9-0.77a15.37 15.37 0 0 0 0.26 0.88l-2.85 0.94a18.37 18.37 0 0 1-0.3-1.05zm0.7 2.1l2.78-1.11a15.4 15.4 0 0 0 0.36 0.83l-2.71 1.27a18.4 18.4 0 0 1-0.44-1zm0.9 1.95l2.65-1.43a15.48 15.48 0 0 0 0.45 0.8l-2.55 1.57a18.48 18.48 0 0 1-0.54-0.94zm1.17 1.87l2.45-1.73a15.56 15.56 0 0 0 0.54 0.73l-2.34 1.87a18.56 18.56 0 0 1-0.65-0.87zm1.37 1.72l2.23-2a15.6 15.6 0 0 0 0.63 0.65l-2.1 2.14a18.6 18.6 0 0 1-0.76-0.79zm1.58 1.56l1.98-2.26c0.22 0.2 0.46 0.39 0.7 0.58l-1.84 2.37a18.59 18.59 0 0 1-0.84-0.7zm1.66 1.28l1.7-2.46a15.52 15.52 0 0 0 0.77 0.5l-1.56 2.56a18.52 18.52 0 0 1-0.91-0.6zm1.87 1.14l1.4-2.65a15.43 15.43 0 0 0 0.82 0.4l-1.24 2.73a18.43 18.43 0 0 1-0.98-0.48zm2 0.91l1.08-2.8a15.37 15.37 0 0 0 0.86 0.3l-0.9 2.86a18.37 18.37 0 0 1-1.04-0.36zm2.1 0.67a18.4 18.4 0 0 0 1.07 0.23l0.56-2.94a15.4 15.4 0 0 1-0.9-0.2l-0.72 2.91zm2.18 0.41a18.57 18.57 0 0 0 1.08 0.1l0.2-2.99a15.57 15.57 0 0 1-0.9-0.09l-0.38 2.98zm2.2 0.15H22v-3h-0.13l-0.03 3z"/>
+ </group>
</vector>
diff --git a/core/res/res/drawable-nodpi/platlogo_m.xml b/core/res/res/drawable-nodpi/platlogo_m.xml
index d9a558d..aacf674 100644
--- a/core/res/res/drawable-nodpi/platlogo_m.xml
+++ b/core/res/res/drawable-nodpi/platlogo_m.xml
@@ -1,5 +1,5 @@
<!--
-Copyright (C) 2016 The Android Open Source Project
+Copyright (C) 2017 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.
@@ -14,59 +14,27 @@
limitations under the License.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="48dp"
- android:height="48dp"
+ android:width="480dp"
+ android:height="480dp"
android:viewportWidth="48.0"
android:viewportHeight="48.0">
+ <!--<path
+ android:pathData="M25.0,25.0m-20.5,0.0a20.5,20.5,0,1,1,41.0,0.0a20.5,20.5,0,1,1,-41.0,0.0"
+ android:fillAlpha="0.066"
+ android:fillColor="#000000"/>-->
<path
- android:fillColor="#FFFFFFFF"
- android:pathData="M33.8,38l-25.5,-25.5l-1.7000003,0.6999998l25.499998,25.5z"/>
+ android:pathData="M24.0,24.0m-20.0,0.0a20.0,20.0,0,1,1,40.0,0.0a20.0,20.0,0,1,1,-40.0,0.0"
+ android:fillColor="#FFC107"/>
<path
- android:fillColor="#FFFFFFFF"
- android:pathData="M40.8,34.8l-25.4,-25.5l-1.6999998,0.6999998l25.5,25.5z"/>
+ android:pathData="M44,24.2010101 L33.9004889,14.101499 L14.101499,33.9004889 L24.2010101,44 C29.2525804,43.9497929 34.2887564,41.9975027 38.1431296,38.1431296 C41.9975027,34.2887564 43.9497929,29.2525804 44,24.2010101 Z"
+ android:fillColor="#FE9F00"/>
<path
- android:fillColor="#FFFFFFFF"
- android:pathData="M11.1,13.1l-0.3,-0.4l1.1,-1.3l0,0l-1.6,0.8l-0.4,-0.4l2.6,-1.2l0.4,0.4l-1.1,1.3l0,0l1.6,-0.8l0.3,0.4L11.1,13.1z"/>
+ android:pathData="M24.0,24.0m-14.0,0.0a14.0,14.0,0,1,1,28.0,0.0a14.0,14.0,0,1,1,-28.0,0.0"
+ android:fillColor="#FED44F"/>
<path
- android:fillColor="#FFFFFFFF"
- android:pathData="M13,14.2l-0.5,-0.5l-0.6,0.2l-0.4,-0.4l3.1,-0.7l0.4,0.4l-2.1,1.7l-0.4,-0.4L13,14.2z M13,13.6l0.3,0.3l0.8,-0.6 l0,0L13,13.6z"/>
+ android:pathData="M37.7829445,26.469236 L29.6578482,18.3441397 L18.3441397,29.6578482 L26.469236,37.7829445 C29.1911841,37.2979273 31.7972024,36.0037754 33.9004889,33.9004889 C36.0037754,31.7972024 37.2979273,29.1911841 37.7829445,26.469236 Z"
+ android:fillColor="#FFC107"/>
<path
- android:fillColor="#FFFFFFFF"
- android:pathData="M16.3,14.6l-1.6,1.2l0,0l2.2,-0.6l0.5,0.5l-2.6,1.2l-0.3,-0.4l0.7,-0.3l1,-0.4l0,0l-2.1,0.5L13.9,16l1.4,-1.1l0,0 l-0.9,0.5l-0.7,0.3l-0.3,-0.4l2.6,-1.2L16.3,14.6z"/>
- <path
- android:fillColor="#FFFFFFFF"
- android:pathData="M17.4,17.8l-0.6,-0.6l-0.7,0.3l0.7,0.7l-0.4,0.2l-1,-1l2.6,-1.2l1,1l-0.4,0.2l-0.7,-0.7L17.2,17l0.6,0.6L17.4,17.8 z"/>
- <path
- android:fillColor="#FFFFFFFF"
- android:pathData="M18.8,18.7L18.8,18.7l1.3,-0.2l0.4,0.4l-2.1,0.3l-0.9,0.4l-0.3,-0.4l1,-0.4l1.2,-1.2l0.4,0.4L18.8,18.7z"/>
- <path
- android:fillColor="#FFFFFFFF"
- android:pathData="M22.2,20.5l-1.6,1.2l0,0l2.2,-0.6l0.5,0.5l-2.6,1.2l-0.3,-0.4l0.7,-0.3l1,-0.4l0,0L20,22.1l-0.2,-0.2l1.4,-1.1l0,0 l-0.9,0.5l-0.7,0.3l-0.3,-0.4l2.6,-1.2L22.2,20.5z"/>
- <path
- android:fillColor="#FFFFFFFF"
- android:pathData="M22,23.6c0,0,0.1,0.1,0.2,0.1c0.1,0,0.2,0,0.3,-0.1l0.3,0.3c-0.2,0.1,-0.4,0.1,-0.6,0.1c-0.2,0,-0.4,-0.1,-0.5,-0.2 c-0.2,-0.2,-0.2,-0.3,-0.1,-0.5c0.1,-0.2,0.2,-0.3,0.5,-0.4l0.2,-0.1c0.3,-0.1,0.5,-0.2,0.8,-0.2c0.2,0,0.5,0.1,0.6,0.3 c0.1,0.1,0.2,0.3,0.1,0.4c0,0.1,-0.2,0.3,-0.4,0.4L23,23.4c0.1,0,0.2,-0.1,0.2,-0.2c0,-0.1,0,-0.1,0,-0.2C23.1,23,23,22.9,22.9,23 c-0.1,0,-0.2,0.1,-0.4,0.1l-0.2,0.1c-0.2,0.1,-0.3,0.1,-0.3,0.2C21.9,23.5,21.9,23.5,22,23.6z"/>
- <path
- android:fillColor="#FFFFFFFF"
- android:pathData="M23.8,25.9l-0.3,-0.4l1.1,-1.3l0,0L22.9,25l-0.4,-0.4l2.6,-1.2l0.4,0.4l-1.1,1.3l0,0l1.6,-0.8l0.3,0.4L23.8,25.9z"/>
- <path
- android:fillColor="#FFFFFFFF"
- android:pathData="M25.7,27l-0.5,-0.5l-0.6,0.2l-0.4,-0.4l3.1,-0.7l0.4,0.4l-2.1,1.7l-0.4,-0.4L25.7,27z M25.7,26.4l0.3,0.3l0.8,-0.6 l0,0L25.7,26.4z"/>
- <path
- android:fillColor="#FFFFFFFF"
- android:pathData="M29,27.4l-1.6,1.2l0,0l2.2,-0.6l0.5,0.5l-2.6,1.2l-0.3,-0.4l0.8,-0.3l1,-0.4l0,0L26.8,29l-0.2,-0.2l1.4,-1.1l0,0 L27,28.1l-0.8,0.3l-0.3,-0.4l2.6,-1.2L29,27.4z"/>
- <path
- android:fillColor="#FFFFFFFF"
- android:pathData="M30,30.6L29.5,30l-0.7,0.3l0.7,0.7L29,31.2l-1,-1l2.6,-1.2l1,1l-0.4,0.2l-0.7,-0.7l-0.6,0.3l0.6,0.6L30,30.6z"/>
- <path
- android:fillColor="#FFFFFFFF"
- android:pathData="M31.5,32.1l-0.6,-0.6L29.8,32l-0.4,-0.4l2.6,-1.2l1,1l-0.4,0.2L32,31l-0.7,0.3l0.6,0.6L31.5,32.1z"/>
- <path
- android:fillColor="#FFFFFFFF"
- android:pathData="M32,33.5L31.6,33L31,33.2l-0.4,-0.4l3.1,-0.7l0.4,0.4l-2.1,1.7l-0.4,-0.4L32,33.5z M32.1,32.9l0.3,0.3l0.8,-0.6 l0,0L32.1,32.9z"/>
- <path
- android:fillColor="#FFFFFFFF"
- android:pathData="M34.3,35.3c-0.3,0.1,-0.5,0.2,-0.8,0.1c-0.2,0,-0.5,-0.1,-0.6,-0.3c-0.2,-0.2,-0.2,-0.4,-0.2,-0.5 c0.1,-0.2,0.2,-0.3,0.6,-0.5l0.8,-0.4c0.3,-0.1,0.6,-0.2,0.9,-0.2c0.3,0,0.5,0.1,0.7,0.3c0.2,0.2,0.3,0.4,0.2,0.5c0,0.2,-0.2,0.3,-0.5,0.5 l-0.3,-0.4c0.2,-0.1,0.3,-0.1,0.3,-0.2c0,-0.1,0,-0.1,-0.1,-0.2C35,34,34.9,34,34.8,34c-0.1,0,-0.3,0,-0.5,0.1l-0.8,0.4 c-0.2,0.1,-0.3,0.2,-0.4,0.2c0,0.1,0,0.1,0,0.2c0.1,0.1,0.2,0.1,0.3,0.1c0.1,0,0.2,0,0.4,-0.1L34.3,35.3z"/>
- <path
- android:fillColor="#FFFFFFFF"
- android:pathData="M36,36.6L35.4,36l-0.7,0.3l0.7,0.7l-0.4,0.2l-1,-1l2.6,-1.2l1,1l-0.4,0.2l-0.7,-0.7l-0.6,0.3l0.6,0.6L36,36.6z"/>
+ android:pathData="M24.0,24.0m-8.0,0.0a8.0,8.0,0,1,1,16.0,0.0a8.0,8.0,0,1,1,-16.0,0.0"
+ android:fillColor="#FFFFFF"/>
</vector>
diff --git a/core/res/res/drawable-nodpi/stat_sys_adb.xml b/core/res/res/drawable-nodpi/stat_sys_adb.xml
index 89e42e6..2e2b395 100644
--- a/core/res/res/drawable-nodpi/stat_sys_adb.xml
+++ b/core/res/res/drawable-nodpi/stat_sys_adb.xml
@@ -1,3 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (C) 2017 The Android Open Source Project
@@ -14,19 +15,23 @@
limitations under the License.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="24dp"
- android:height="24dp"
- android:viewportWidth="24.0"
- android:viewportHeight="24.0">
- <path
- android:fillColor="#FF000000"
- android:pathData="M12.0,12.0m-10.0,0.0a10.0,10.0,0,1,1,20.0,0.0a10.0,10.0,0,1,1,-20.0,0.0"
- android:fillAlpha="0.25"/>
- <path
- android:fillColor="#FF000000"
- android:pathData="M12,22 C6.4771525,22 2,17.5228475 2,12 C2,6.4771525 6.4771525,2 12,2 C17.5228475,2 22,6.4771525 22,12 C22,17.5228475 17.5228475,22 12,22 Z M12,18.5 C15.5898509,18.5 18.5,15.5898509 18.5,12 C18.5,8.41014913 15.5898509,5.5 12,5.5 C8.41014913,5.5 5.5,8.41014913 5.5,12 C5.5,15.5898509 8.41014913,18.5 12,18.5 Z"/>
- <path
- android:fillColor="#FF000000"
- android:pathData="M12,18.5 C8.41014913,18.5 5.5,15.5898509 5.5,12 C5.5,8.41014913 8.41014913,5.5 12,5.5 C15.5898509,5.5 18.5,8.41014913 18.5,12 C18.5,15.5898509 15.5898509,18.5 12,18.5 Z M12,15 C13.6568542,15 15,13.6568542 15,12 C15,10.3431458 13.6568542,9 12,9 C10.3431458,9 9,10.3431458 9,12 C9,13.6568542 10.3431458,15 12,15 Z"
- android:fillAlpha="0.25"/>
-</vector>
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+ <group>
+ <path
+ android:fillColor="#FFFFFF"
+ android:fillAlpha=".33"
+ android:fillType="evenOdd"
+ android:pathData="M5.71 18.29A8.99 8.99 0 0 0 22 13c0-3-1.46-5.65-3.71-7.29A8.99 8.99 0 0 0 2 11c0 3 1.46 5.65 3.71 7.29z"/>
+ <path
+ android:fillColor="#FFFFFF"
+ android:fillType="evenOdd"
+ android:pathData="M7.25 19.18A8.5 8.5 0 0 0 19.19 7.24 9 9 0 0 1 7.24 19.19z"/>
+ <path
+ android:fillColor="#FFFFFF"
+ android:fillAlpha=".33"
+ android:pathData="M10.5 3a0.5 0.5 0 1 1 1 0v2.05a0.5 0.5 0 1 1-1 0V3zm3.1 0.42a0.5 0.5 0 0 1 0.93 0.39l-0.8 1.88A0.5 0.5 0 1 1 12.8 5.3l0.8-1.88zm2.7 1.57a0.5 0.5 0 1 1 0.71 0.7l-1.45 1.46a0.5 0.5 0 0 1-0.7-0.71l1.44-1.45zm1.9 2.5a0.5 0.5 0 0 1 0.38 0.92l-1.9 0.77a0.5 0.5 0 0 1-0.37-0.93l1.9-0.77zM19 10.5a0.5 0.5 0 1 1 0 1h-2.05a0.5 0.5 0 0 1 0-1H19zm-0.42 3.1a0.5 0.5 0 0 1-0.39 0.93l-1.88-0.8a0.5 0.5 0 1 1 0.39-0.92l1.88 0.8zm-1.57 2.7a0.5 0.5 0 1 1-0.7 0.71l-1.46-1.45a0.5 0.5 0 0 1 0.71-0.7l1.45 1.44zm-2.5 1.9a0.5 0.5 0 1 1-0.92 0.38l-0.77-1.9a0.5 0.5 0 0 1 0.93-0.37l0.77 1.9zM11.5 19a0.5 0.5 0 1 1-1 0v-2.05a0.5 0.5 0 0 1 1 0V19zm-3.1-0.42a0.5 0.5 0 0 1-0.93-0.39l0.8-1.88A0.5 0.5 0 0 1 9.2 16.7l-0.8 1.88zm-2.7-1.57a0.5 0.5 0 1 1-0.71-0.7l1.45-1.46a0.5 0.5 0 0 1 0.7 0.71L5.7 17.01zm-1.9-2.48a0.5 0.5 0 0 1-0.38-0.92l1.88-0.8a0.5 0.5 0 0 1 0.4 0.92l-1.9 0.8zM3 11.5a0.5 0.5 0 1 1 0-1h2.05a0.5 0.5 0 1 1 0 1H3zm0.42-3.1A0.5 0.5 0 0 1 3.8 7.46l1.88 0.8A0.5 0.5 0 1 1 5.3 9.2L3.42 8.4zm1.57-2.7a0.5 0.5 0 1 1 0.7-0.71l1.46 1.45a0.5 0.5 0 0 1-0.71 0.7L4.99 5.7zm2.5-1.9A0.5 0.5 0 0 1 8.4 3.41l0.77 1.9a0.5 0.5 0 0 1-0.93 0.37L7.48 3.8z"/>
+ </group>
+</vector>
\ No newline at end of file
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index 8151ceb..105ef44 100644
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -1891,6 +1891,7 @@
<enum name="KEYCODE_SYSTEM_NAVIGATION_DOWN" value="281" />
<enum name="KEYCODE_SYSTEM_NAVIGATION_LEFT" value="282" />
<enum name="KEYCODE_SYSTEM_NAVIGATION_RIGHT" value="283" />
+ <enum name="KEYCODE_ALL_APPS" value="284" />
</attr>
<!-- ***************************************************************** -->
@@ -2055,6 +2056,14 @@
Corresponds to {@link android.view.Window#setNavigationBarColor(int)}. -->
<attr name="navigationBarColor" format="color" />
+ <!-- @hide
+ Shows 1dp line of the specified color between the navigation bar and the app content.
+ <p>For this to take effect, the window must be drawing the system bar backgrounds with
+ {@link android.R.attr#windowDrawsSystemBarBackgrounds} and the navigation bar must not
+ have been requested to be translucent with
+ {@link android.R.attr#windowTranslucentNavigation}. -->
+ <attr name="navigationBarDividerColor" format="color" />
+
<!-- The duration, in milliseconds, of the window background fade duration
when transitioning into or away from an Activity when called with an
Activity Transition. Corresponds to
@@ -2087,6 +2096,16 @@
{@link android.R.attr#windowBackground}.
-->
<attr name="windowSplashscreenContent" format="reference" />
+
+ <!-- @hide If set, the navigation bar will be drawn such that it is
+ compatible with a light navigation bar background.
+ <p>For this to take effect, the window must be drawing the system bar backgrounds with
+ {@link android.R.attr#windowDrawsSystemBarBackgrounds} and the navigation bar must not
+ have been requested to be translucent with
+ {@link android.R.attr#windowTranslucentNavigation}.
+ Corresponds to setting {@link android.view.View#SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR} on
+ the decor view. -->
+ <attr name="windowLightNavigationBar" format="boolean" />
</declare-styleable>
<!-- The set of attributes that describe a AlertDialog's theme. -->
diff --git a/core/res/res/values/themes_device_defaults.xml b/core/res/res/values/themes_device_defaults.xml
index 8755e37..bf0c906 100644
--- a/core/res/res/values/themes_device_defaults.xml
+++ b/core/res/res/values/themes_device_defaults.xml
@@ -745,6 +745,11 @@
<item name="colorSecondary">@color/secondary_device_default_settings_light</item>
<item name="colorAccent">@color/accent_device_default_light</item>
<item name="colorEdgeEffect">@android:color/black</item>
+
+ <!-- Add white nav bar with divider that matches material -->
+ <item name="navigationBarDividerColor">#1f000000</item>
+ <item name="navigationBarColor">@android:color/white</item>
+ <item name="windowLightNavigationBar">true</item>
</style>
<!-- @hide DeviceDefault theme for a window that should use Settings theme colors
diff --git a/core/tests/coretests/src/android/database/NewDatabasePerformanceTestSuite.java b/core/tests/coretests/src/android/database/NewDatabasePerformanceTestSuite.java
index c9db034..6156692 100644
--- a/core/tests/coretests/src/android/database/NewDatabasePerformanceTestSuite.java
+++ b/core/tests/coretests/src/android/database/NewDatabasePerformanceTestSuite.java
@@ -23,6 +23,7 @@
TestSuite suite =
new TestSuite(NewDatabasePerformanceTestSuite.class.getName());
+ suite.addTestSuite(NewDatabasePerformanceTests.CreateTable100.class);
suite.addTestSuite(NewDatabasePerformanceTests.Insert100.class);
suite.addTestSuite(NewDatabasePerformanceTests.InsertIndexed100.class);
suite.addTestSuite(NewDatabasePerformanceTests.Select100.class);
diff --git a/core/tests/coretests/src/android/database/NewDatabasePerformanceTests.java b/core/tests/coretests/src/android/database/NewDatabasePerformanceTests.java
index f8d8e5e..bcd9060 100644
--- a/core/tests/coretests/src/android/database/NewDatabasePerformanceTests.java
+++ b/core/tests/coretests/src/android/database/NewDatabasePerformanceTests.java
@@ -34,8 +34,9 @@
public class NewDatabasePerformanceTests {
private static final String TAG = "NewDatabasePerformanceTests";
- // Edit this to change the test run times. The original is 100.
- private static final int SIZE_MULTIPLIER = 100;
+ private static final int DATASET_SIZE = 100; // Size of dataset to use for testing
+ private static final int FAST_OP_MULTIPLIER = 25;
+ private static final int FAST_OP_COUNT = FAST_OP_MULTIPLIER * DATASET_SIZE;
public static class PerformanceBase extends TestCase
implements PerformanceTestCase {
@@ -50,16 +51,21 @@
if (mDatabaseFile.exists()) {
mDatabaseFile.delete();
}
- mDatabase =
- SQLiteDatabase.openOrCreateDatabase(mDatabaseFile.getPath(),
- null);
+ mDatabase = SQLiteDatabase.openOrCreateDatabase(mDatabaseFile.getPath(), null);
assertTrue(mDatabase != null);
mDatabase.setVersion(CURRENT_DATABASE_VERSION);
+ mDatabase.beginTransactionNonExclusive();
+ prepareForTest();
+ mDatabase.setTransactionSuccessful();
+ mDatabase.endTransaction();
mSetupFinishedTime = System.currentTimeMillis();
Log.i(TAG, "Setup for " + getClass().getSimpleName() + " took "
+ (mSetupFinishedTime - setupStarted) + " ms");
}
+ protected void prepareForTest() {
+ }
+
public void tearDown() {
long duration = System.currentTimeMillis() - mSetupFinishedTime;
Log.i(TAG, "Test " + getClass().getSimpleName() + " took " + duration + " ms");
@@ -76,7 +82,7 @@
return 0;
}
- public String numberName(int number) {
+ String numberName(int number) {
String result = "";
if (number >= 1000) {
@@ -106,36 +112,50 @@
return result;
}
+
+ void checkCursor(Cursor c) {
+ c.getColumnCount();
+ c.close();
+ }
+ }
+
+ /**
+ * Test CREATE SIZE tables with 1 row.
+ */
+ public static class CreateTable100 extends PerformanceBase {
+ public void testRun() {
+ for (int i = 0; i < DATASET_SIZE; i++) {
+ String t = "t" + i;
+ mDatabase.execSQL("CREATE TABLE " + t + "(a INTEGER, b INTEGER, c VARCHAR(100))");
+ mDatabase.execSQL("INSERT INTO " + t + " VALUES(" + i + "," + i + ",'"
+ + numberName(i) + "')");
+ }
+ }
}
/**
* Test 100 inserts.
*/
-
public static class Insert100 extends PerformanceBase {
- private static final int SIZE = SIZE_MULTIPLIER;
-
- private String[] statements = new String[SIZE];
+ private String[] mStatements = new String[DATASET_SIZE];
@Override
- public void setUp() {
- super.setUp();
+ protected void prepareForTest() {
Random random = new Random(42);
- for (int i = 0; i < SIZE; i++) {
+ for (int i = 0; i < DATASET_SIZE; i++) {
int r = random.nextInt(100000);
- statements[i] =
+ mStatements[i] =
"INSERT INTO t1 VALUES(" + i + "," + r + ",'"
+ numberName(r) + "')";
}
- mDatabase
- .execSQL("CREATE TABLE t1(a INTEGER, b INTEGER, c VARCHAR(100))");
+ mDatabase.execSQL("CREATE TABLE t1(a INTEGER, b INTEGER, c VARCHAR(100))");
}
public void testRun() {
- for (int i = 0; i < SIZE; i++) {
- mDatabase.execSQL(statements[i]);
+ for (int i = 0; i < DATASET_SIZE; i++) {
+ mDatabase.execSQL(mStatements[i]);
}
}
}
@@ -145,30 +165,25 @@
*/
public static class InsertIndexed100 extends PerformanceBase {
- private static final int SIZE = SIZE_MULTIPLIER;
-
- private String[] statements = new String[SIZE];
+ private String[] mStatements = new String[DATASET_SIZE];
@Override
- public void setUp() {
- super.setUp();
+ protected void prepareForTest() {
Random random = new Random(42);
- for (int i = 0; i < SIZE; i++) {
+ for (int i = 0; i < DATASET_SIZE; i++) {
int r = random.nextInt(100000);
- statements[i] =
- "INSERT INTO t1 VALUES(" + i + "," + r + ",'"
- + numberName(r) + "')";
+ mStatements[i] = "INSERT INTO t1 VALUES(" + i + "," + r + ",'"
+ + numberName(r) + "')";
}
- mDatabase
- .execSQL("CREATE TABLE t1(a INTEGER, b INTEGER, c VARCHAR(100))");
+ mDatabase.execSQL("CREATE TABLE t1(a INTEGER, b INTEGER, c VARCHAR(100))");
mDatabase.execSQL("CREATE INDEX i1c ON t1(c)");
}
public void testRun() {
- for (int i = 0; i < SIZE; i++) {
- mDatabase.execSQL(statements[i]);
+ for (int i = 0; i < DATASET_SIZE; i++) {
+ mDatabase.execSQL(mStatements[i]);
}
}
}
@@ -176,41 +191,35 @@
/**
* 100 SELECTs without an index
*/
-
public static class Select100 extends PerformanceBase {
- private static final int SIZE = SIZE_MULTIPLIER;
- private static final int REPEAT_COUNT = 10;
private static final String[] COLUMNS = {"count(*)", "avg(b)"};
- private String[] where = new String[SIZE];
+ private String[] mWhere = new String[DATASET_SIZE];
@Override
- public void setUp() {
- super.setUp();
+ protected void prepareForTest() {
Random random = new Random(42);
mDatabase
.execSQL("CREATE TABLE t1(a INTEGER, b INTEGER, c VARCHAR(100))");
- for (int i = 0; i < SIZE; i++) {
+ for (int i = 0; i < DATASET_SIZE; i++) {
int r = random.nextInt(100000);
mDatabase.execSQL("INSERT INTO t1 VALUES(" + i + "," + r + ",'"
+ numberName(r) + "')");
}
- for (int i = 0; i < SIZE; i++) {
+ for (int i = 0; i < DATASET_SIZE; i++) {
int lower = i * 100;
int upper = (i + 10) * 100;
- where[i] = "b >= " + lower + " AND b < " + upper;
+ mWhere[i] = "b >= " + lower + " AND b < " + upper;
}
}
public void testRun() {
- for (int iter = 0; iter < REPEAT_COUNT; iter++) {
- for (int i = 0; i < SIZE; i++) {
- mDatabase
- .query("t1", COLUMNS, where[i], null, null, null, null);
- }
+ for (int i = 0; i < FAST_OP_COUNT; i++) {
+ checkCursor(mDatabase
+ .query("t1", COLUMNS, mWhere[i % DATASET_SIZE], null, null, null, null));
}
}
}
@@ -219,37 +228,32 @@
* 100 SELECTs on a string comparison
*/
public static class SelectStringComparison100 extends PerformanceBase {
- private static final int SIZE = SIZE_MULTIPLIER;
- private static final int REPEAT_COUNT = 10;
private static final String[] COLUMNS = {"count(*)", "avg(b)"};
- private String[] where = new String[SIZE];
+ private String[] mWhere = new String[DATASET_SIZE];
@Override
- public void setUp() {
- super.setUp();
+ protected void prepareForTest() {
Random random = new Random(42);
mDatabase
.execSQL("CREATE TABLE t1(a INTEGER, b INTEGER, c VARCHAR(100))");
- for (int i = 0; i < SIZE; i++) {
+ for (int i = 0; i < DATASET_SIZE; i++) {
int r = random.nextInt(100000);
mDatabase.execSQL("INSERT INTO t1 VALUES(" + i + "," + r + ",'"
+ numberName(r) + "')");
}
- for (int i = 0; i < SIZE; i++) {
- where[i] = "c LIKE '" + numberName(i) + "'";
+ for (int i = 0; i < DATASET_SIZE; i++) {
+ mWhere[i] = "c LIKE '" + numberName(i) + "'";
}
}
public void testRun() {
- for (int iter = 0; iter < REPEAT_COUNT; iter++) {
- for (int i = 0; i < SIZE; i++) {
- mDatabase
- .query("t1", COLUMNS, where[i], null, null, null, null);
- }
+ for (int i = 0; i < FAST_OP_COUNT; i++) {
+ checkCursor(mDatabase
+ .query("t1", COLUMNS, mWhere[i % DATASET_SIZE], null, null, null, null));
}
}
}
@@ -258,40 +262,35 @@
* 100 SELECTs with an index
*/
public static class SelectIndex100 extends PerformanceBase {
- private static final int SIZE = SIZE_MULTIPLIER;
- private static final int REPEAT_COUNT = 10;
+ private static final int TABLE_SIZE = 100;
private static final String[] COLUMNS = {"count(*)", "avg(b)"};
- private String[] where = new String[SIZE];
+ private String[] mWhere = new String[TABLE_SIZE];
@Override
- public void setUp() {
- super.setUp();
+ protected void prepareForTest() {
Random random = new Random(42);
- mDatabase
- .execSQL("CREATE TABLE t1(a INTEGER, b INTEGER, c VARCHAR(100))");
+ mDatabase.execSQL("CREATE TABLE t1(a INTEGER, b INTEGER, c VARCHAR(100))");
mDatabase.execSQL("CREATE INDEX i1b ON t1(b)");
- for (int i = 0; i < SIZE; i++) {
+ for (int i = 0; i < TABLE_SIZE; i++) {
int r = random.nextInt(100000);
mDatabase.execSQL("INSERT INTO t1 VALUES(" + i + "," + r + ",'"
+ numberName(r) + "')");
}
- for (int i = 0; i < SIZE; i++) {
+ for (int i = 0; i < TABLE_SIZE; i++) {
int lower = i * 100;
int upper = (i + 10) * 100;
- where[i] = "b >= " + lower + " AND b < " + upper;
+ mWhere[i] = "b >= " + lower + " AND b < " + upper;
}
}
public void testRun() {
- for (int iter = 0; iter < REPEAT_COUNT; iter++) {
- for (int i = 0; i < SIZE; i++) {
- mDatabase
- .query("t1", COLUMNS, where[i], null, null, null, null);
- }
+ for (int i = 0; i < FAST_OP_COUNT; i++) {
+ checkCursor(mDatabase
+ .query("t1", COLUMNS, mWhere[i % TABLE_SIZE], null, null, null, null));
}
}
}
@@ -300,27 +299,22 @@
* INNER JOIN without an index
*/
public static class InnerJoin100 extends PerformanceBase {
- private static final int SIZE = SIZE_MULTIPLIER;
- private static final int REPEAT_COUNT = 10;
private static final String[] COLUMNS = {"t1.a"};
@Override
- public void setUp() {
- super.setUp();
+ protected void prepareForTest() {
Random random = new Random(42);
- mDatabase
- .execSQL("CREATE TABLE t1(a INTEGER, b INTEGER, c VARCHAR(100))");
- mDatabase
- .execSQL("CREATE TABLE t2(a INTEGER, b INTEGER, c VARCHAR(100))");
+ mDatabase.execSQL("CREATE TABLE t1(a INTEGER, b INTEGER, c VARCHAR(100))");
+ mDatabase.execSQL("CREATE TABLE t2(a INTEGER, b INTEGER, c VARCHAR(100))");
- for (int i = 0; i < SIZE; i++) {
+ for (int i = 0; i < DATASET_SIZE; i++) {
int r = random.nextInt(100000);
mDatabase.execSQL("INSERT INTO t1 VALUES(" + i + "," + r + ",'"
+ numberName(r) + "')");
}
- for (int i = 0; i < SIZE; i++) {
+ for (int i = 0; i < DATASET_SIZE; i++) {
int r = random.nextInt(100000);
mDatabase.execSQL("INSERT INTO t2 VALUES(" + i + "," + r + ",'"
+ numberName(r) + "')");
@@ -328,9 +322,9 @@
}
public void testRun() {
- for (int iter = 0; iter < REPEAT_COUNT; iter++) {
- mDatabase.query("t1 INNER JOIN t2 ON t1.b = t2.b", COLUMNS, null,
- null, null, null, null);
+ for (int i = 0; i < FAST_OP_COUNT; i++) {
+ checkCursor(mDatabase.query("t1 INNER JOIN t2 ON t1.b = t2.b", COLUMNS, null,
+ null, null, null, null));
}
}
}
@@ -340,29 +334,24 @@
*/
public static class InnerJoinOneSide100 extends PerformanceBase {
- private static final int SIZE = SIZE_MULTIPLIER;
- private static final int REPEAT_COUNT = 10;
private static final String[] COLUMNS = {"t1.a"};
@Override
- public void setUp() {
- super.setUp();
+ protected void prepareForTest() {
Random random = new Random(42);
- mDatabase
- .execSQL("CREATE TABLE t1(a INTEGER, b INTEGER, c VARCHAR(100))");
- mDatabase
- .execSQL("CREATE TABLE t2(a INTEGER, b INTEGER, c VARCHAR(100))");
+ mDatabase.execSQL("CREATE TABLE t1(a INTEGER, b INTEGER, c VARCHAR(100))");
+ mDatabase.execSQL("CREATE TABLE t2(a INTEGER, b INTEGER, c VARCHAR(100))");
mDatabase.execSQL("CREATE INDEX i1b ON t1(b)");
- for (int i = 0; i < SIZE; i++) {
+ for (int i = 0; i < DATASET_SIZE; i++) {
int r = random.nextInt(100000);
mDatabase.execSQL("INSERT INTO t1 VALUES(" + i + "," + r + ",'"
+ numberName(r) + "')");
}
- for (int i = 0; i < SIZE; i++) {
+ for (int i = 0; i < DATASET_SIZE; i++) {
int r = random.nextInt(100000);
mDatabase.execSQL("INSERT INTO t2 VALUES(" + i + "," + r + ",'"
+ numberName(r) + "')");
@@ -370,9 +359,9 @@
}
public void testRun() {
- for (int iter = 0; iter < REPEAT_COUNT; iter++) {
- mDatabase.query("t1 INNER JOIN t2 ON t1.b = t2.b", COLUMNS, null,
- null, null, null, null);
+ for (int i = 0; i < FAST_OP_COUNT; i++) {
+ checkCursor(mDatabase.query("t1 INNER JOIN t2 ON t1.b = t2.b", COLUMNS, null,
+ null, null, null, null));
}
}
}
@@ -381,29 +370,24 @@
* INNER JOIN without an index on one side
*/
public static class InnerJoinNoIndex100 extends PerformanceBase {
- private static final int SIZE = SIZE_MULTIPLIER;
- private static final int REPEAT_COUNT = 10;
private static final String[] COLUMNS = {"t1.a"};
@Override
- public void setUp() {
- super.setUp();
+ protected void prepareForTest() {
Random random = new Random(42);
- mDatabase
- .execSQL("CREATE TABLE t1(a INTEGER, b INTEGER, c VARCHAR(100))");
- mDatabase
- .execSQL("CREATE TABLE t2(a INTEGER, b INTEGER, c VARCHAR(100))");
+ mDatabase.execSQL("CREATE TABLE t1(a INTEGER, b INTEGER, c VARCHAR(100))");
+ mDatabase.execSQL("CREATE TABLE t2(a INTEGER, b INTEGER, c VARCHAR(100))");
mDatabase.execSQL("CREATE INDEX i1b ON t1(b)");
- for (int i = 0; i < SIZE; i++) {
+ for (int i = 0; i < DATASET_SIZE; i++) {
int r = random.nextInt(100000);
mDatabase.execSQL("INSERT INTO t1 VALUES(" + i + "," + r + ",'"
+ numberName(r) + "')");
}
- for (int i = 0; i < SIZE; i++) {
+ for (int i = 0; i < DATASET_SIZE; i++) {
int r = random.nextInt(100000);
mDatabase.execSQL("INSERT INTO t2 VALUES(" + i + "," + r + ",'"
+ numberName(r) + "')");
@@ -411,9 +395,10 @@
}
public void testRun() {
- for (int iter = 0; iter < REPEAT_COUNT; iter++) {
- mDatabase.query("t1 INNER JOIN t2 ON t1.c = t2.c", COLUMNS, null,
- null, null, null, null);
+ for (int i = 0; i < FAST_OP_COUNT; i++) {
+ checkCursor(mDatabase
+ .query("t1 INNER JOIN t2 ON t1.c = t2.c", COLUMNS, null, null, null, null,
+ null));
}
}
}
@@ -422,49 +407,44 @@
* 100 SELECTs with subqueries. Subquery is using an index
*/
public static class SelectSubQIndex100 extends PerformanceBase {
- private static final int SIZE = SIZE_MULTIPLIER;
- private static final int REPEAT_COUNT = 10;
private static final String[] COLUMNS = {"t1.a"};
- private String[] where = new String[SIZE];
+ private String[] mWhere = new String[DATASET_SIZE];
@Override
- public void setUp() {
- super.setUp();
+ protected void prepareForTest() {
Random random = new Random(42);
- mDatabase
- .execSQL("CREATE TABLE t1(a INTEGER, b INTEGER, c VARCHAR(100))");
- mDatabase
- .execSQL("CREATE TABLE t2(a INTEGER, b INTEGER, c VARCHAR(100))");
+ mDatabase.execSQL("CREATE TABLE t1(a INTEGER, b INTEGER, c VARCHAR(100))");
+ mDatabase.execSQL("CREATE TABLE t2(a INTEGER, b INTEGER, c VARCHAR(100))");
mDatabase.execSQL("CREATE INDEX i2b ON t2(b)");
- for (int i = 0; i < SIZE; i++) {
+ for (int i = 0; i < DATASET_SIZE; i++) {
int r = random.nextInt(100000);
mDatabase.execSQL("INSERT INTO t1 VALUES(" + i + "," + r + ",'"
+ numberName(r) + "')");
}
- for (int i = 0; i < SIZE; i++) {
+ for (int i = 0; i < DATASET_SIZE; i++) {
int r = random.nextInt(100000);
mDatabase.execSQL("INSERT INTO t2 VALUES(" + i + "," + r + ",'"
+ numberName(r) + "')");
}
- for (int i = 0; i < SIZE; i++) {
+ for (int i = 0; i < DATASET_SIZE; i++) {
int lower = i * 100;
int upper = (i + 10) * 100;
- where[i] =
+ mWhere[i] =
"t1.b IN (SELECT t2.b FROM t2 WHERE t2.b >= " + lower
+ " AND t2.b < " + upper + ")";
}
}
public void testRun() {
- for (int i = 0; i < SIZE; i++) {
- mDatabase
- .query("t1", COLUMNS, where[i], null, null, null, null);
+ for (int i = 0; i < FAST_OP_COUNT; i++) {
+ checkCursor(mDatabase
+ .query("t1", COLUMNS, mWhere[i % DATASET_SIZE], null, null, null, null));
}
}
}
@@ -473,38 +453,32 @@
* 100 SELECTs on string comparison with Index
*/
public static class SelectIndexStringComparison100 extends PerformanceBase {
- private static final int SIZE = SIZE_MULTIPLIER;
- private static final int REPEAT_COUNT = 10;
private static final String[] COLUMNS = {"count(*)", "avg(b)"};
- private String[] where = new String[SIZE];
+ private String[] mWhere = new String[DATASET_SIZE];
@Override
- public void setUp() {
- super.setUp();
+ protected void prepareForTest() {
Random random = new Random(42);
- mDatabase
- .execSQL("CREATE TABLE t1(a INTEGER, b INTEGER, c VARCHAR(100))");
+ mDatabase.execSQL("CREATE TABLE t1(a INTEGER, b INTEGER, c VARCHAR(100))");
mDatabase.execSQL("CREATE INDEX i3c ON t1(c)");
- for (int i = 0; i < SIZE; i++) {
+ for (int i = 0; i < DATASET_SIZE; i++) {
int r = random.nextInt(100000);
mDatabase.execSQL("INSERT INTO t1 VALUES(" + i + "," + r + ",'"
+ numberName(r) + "')");
}
- for (int i = 0; i < SIZE; i++) {
- where[i] = "c LIKE '" + numberName(i) + "'";
+ for (int i = 0; i < DATASET_SIZE; i++) {
+ mWhere[i] = "c LIKE '" + numberName(i) + "'";
}
}
public void testRun() {
- for (int iter = 0; iter < REPEAT_COUNT; iter++) {
- for (int i = 0; i < SIZE; i++) {
- mDatabase
- .query("t1", COLUMNS, where[i], null, null, null, null);
- }
+ for (int i = 0; i < FAST_OP_COUNT; i++) {
+ checkCursor(mDatabase
+ .query("t1", COLUMNS, mWhere[i % DATASET_SIZE], null, null, null, null));
}
}
}
@@ -513,19 +487,15 @@
* 100 SELECTs on integer
*/
public static class SelectInteger100 extends PerformanceBase {
- private static final int SIZE = SIZE_MULTIPLIER;
- private static final int REPEAT_COUNT = 10;
private static final String[] COLUMNS = {"b"};
@Override
- public void setUp() {
- super.setUp();
+ protected void prepareForTest() {
Random random = new Random(42);
- mDatabase
- .execSQL("CREATE TABLE t1(a INTEGER, b INTEGER, c VARCHAR(100))");
+ mDatabase.execSQL("CREATE TABLE t1(a INTEGER, b INTEGER, c VARCHAR(100))");
- for (int i = 0; i < SIZE; i++) {
+ for (int i = 0; i < DATASET_SIZE; i++) {
int r = random.nextInt(100000);
mDatabase.execSQL("INSERT INTO t1 VALUES(" + i + "," + r + ",'"
+ numberName(r) + "')");
@@ -534,10 +504,8 @@
}
public void testRun() {
- for (int iter = 0; iter < REPEAT_COUNT; iter++) {
- for (int i = 0; i < SIZE; i++) {
- mDatabase.query("t1", COLUMNS, null, null, null, null, null);
- }
+ for (int i = 0; i < FAST_OP_COUNT; i++) {
+ checkCursor(mDatabase.query("t1", COLUMNS, null, null, null, null, null));
}
}
}
@@ -546,19 +514,16 @@
* 100 SELECTs on String
*/
public static class SelectString100 extends PerformanceBase {
- private static final int SIZE = SIZE_MULTIPLIER;
- private static final int REPEAT_COUNT = 10;
private static final String[] COLUMNS = {"c"};
@Override
- public void setUp() {
- super.setUp();
+ protected void prepareForTest() {
Random random = new Random(42);
mDatabase
.execSQL("CREATE TABLE t1(a INTEGER, b INTEGER, c VARCHAR(100))");
- for (int i = 0; i < SIZE; i++) {
+ for (int i = 0; i < DATASET_SIZE; i++) {
int r = random.nextInt(100000);
mDatabase.execSQL("INSERT INTO t1 VALUES(" + i + "," + r + ",'"
+ numberName(r) + "')");
@@ -566,10 +531,8 @@
}
public void testRun() {
- for (int iter = 0; iter < REPEAT_COUNT; iter++) {
- for (int i = 0; i < SIZE; i++) {
- mDatabase.query("t1", COLUMNS, null, null, null, null, null);
- }
+ for (int i = 0; i < FAST_OP_COUNT; i++) {
+ mDatabase.query("t1", COLUMNS, null, null, null, null, null);
}
}
}
@@ -578,20 +541,17 @@
* 100 SELECTs on integer with index
*/
public static class SelectIntegerIndex100 extends PerformanceBase {
- private static final int SIZE = SIZE_MULTIPLIER;
- private static final int REPEAT_COUNT = 10;
private static final String[] COLUMNS = {"b"};
@Override
- public void setUp() {
- super.setUp();
+ protected void prepareForTest() {
Random random = new Random(42);
mDatabase
.execSQL("CREATE TABLE t1(a INTEGER, b INTEGER, c VARCHAR(100))");
mDatabase.execSQL("CREATE INDEX i1b on t1(b)");
- for (int i = 0; i < SIZE; i++) {
+ for (int i = 0; i < DATASET_SIZE; i++) {
int r = random.nextInt(100000);
mDatabase.execSQL("INSERT INTO t1 VALUES(" + i + "," + r + ",'"
+ numberName(r) + "')");
@@ -600,10 +560,8 @@
}
public void testRun() {
- for (int iter = 0; iter < REPEAT_COUNT; iter++) {
- for (int i = 0; i < SIZE; i++) {
- mDatabase.query("t1", COLUMNS, null, null, null, null, null);
- }
+ for (int i = 0; i < FAST_OP_COUNT; i++) {
+ mDatabase.query("t1", COLUMNS, null, null, null, null, null);
}
}
}
@@ -612,20 +570,16 @@
* 100 SELECTs on String with index
*/
public static class SelectIndexString100 extends PerformanceBase {
- private static final int SIZE = SIZE_MULTIPLIER;
- private static final int REPEAT_COUNT = 10;
private static final String[] COLUMNS = {"c"};
@Override
- public void setUp() {
- super.setUp();
+ protected void prepareForTest() {
Random random = new Random(42);
- mDatabase
- .execSQL("CREATE TABLE t1(a INTEGER, b INTEGER, c VARCHAR(100))");
+ mDatabase.execSQL("CREATE TABLE t1(a INTEGER, b INTEGER, c VARCHAR(100))");
mDatabase.execSQL("CREATE INDEX i1c ON t1(c)");
- for (int i = 0; i < SIZE; i++) {
+ for (int i = 0; i < DATASET_SIZE; i++) {
int r = random.nextInt(100000);
mDatabase.execSQL("INSERT INTO t1 VALUES(" + i + "," + r + ",'"
+ numberName(r) + "')");
@@ -633,10 +587,8 @@
}
public void testRun() {
- for (int iter = 0; iter < REPEAT_COUNT; iter++) {
- for (int i = 0; i < SIZE; i++) {
- mDatabase.query("t1", COLUMNS, null, null, null, null, null);
- }
+ for (int i = 0; i < FAST_OP_COUNT; i++) {
+ checkCursor(mDatabase.query("t1", COLUMNS, null, null, null, null, null));
}
}
@@ -646,40 +598,33 @@
* 100 SELECTs on String with starts with
*/
public static class SelectStringStartsWith100 extends PerformanceBase {
- private static final int SIZE = SIZE_MULTIPLIER;
- private static final int REPEAT_COUNT = 10;
private static final String[] COLUMNS = {"c"};
- private String[] where = new String[SIZE];
+ private String[] mWhere = new String[DATASET_SIZE];
@Override
- public void setUp() {
- super.setUp();
+ protected void prepareForTest() {
Random random = new Random(42);
- mDatabase
- .execSQL("CREATE TABLE t1(a INTEGER, b INTEGER, c VARCHAR(100))");
+ mDatabase.execSQL("CREATE TABLE t1(a INTEGER, b INTEGER, c VARCHAR(100))");
mDatabase.execSQL("CREATE INDEX i1c ON t1(c)");
- for (int i = 0; i < SIZE; i++) {
+ for (int i = 0; i < DATASET_SIZE; i++) {
int r = random.nextInt(100000);
mDatabase.execSQL("INSERT INTO t1 VALUES(" + i + "," + r + ",'"
+ numberName(r) + "')");
}
- for (int i = 0; i < SIZE; i++) {
+ for (int i = 0; i < DATASET_SIZE; i++) {
int r = random.nextInt(100000);
- where[i] = "c LIKE '" + numberName(r).substring(0, 1) + "*'";
+ mWhere[i] = "c LIKE '" + numberName(r).substring(0, 1) + "*'";
}
}
public void testRun() {
- for (int iter = 0; iter < REPEAT_COUNT; iter++) {
- for (int i = 0; i < SIZE; i++) {
- mDatabase
- .query("t1", COLUMNS, where[i], null, null, null, null);
- }
+ for (int i = 0; i < FAST_OP_COUNT; i++) {
+ mDatabase.query("t1", COLUMNS, mWhere[i % DATASET_SIZE], null, null, null, null);
}
}
}
@@ -688,18 +633,15 @@
* 100 Deletes on an indexed table
*/
public static class DeleteIndexed100 extends PerformanceBase {
- private static final int SIZE = SIZE_MULTIPLIER;
@Override
- public void setUp() {
- super.setUp();
+ protected void prepareForTest() {
Random random = new Random(42);
- mDatabase
- .execSQL("CREATE TABLE t1(a INTEGER, b INTEGER, c VARCHAR(100))");
+ mDatabase.execSQL("CREATE TABLE t1(a INTEGER, b INTEGER, c VARCHAR(100))");
mDatabase.execSQL("CREATE INDEX i3c ON t1(c)");
- for (int i = 0; i < SIZE; i++) {
+ for (int i = 0; i < DATASET_SIZE; i++) {
int r = random.nextInt(100000);
mDatabase.execSQL("INSERT INTO t1 VALUES(" + i + "," + r + ",'"
+ numberName(r) + "')");
@@ -708,7 +650,7 @@
}
public void testRun() {
- for (int i = 0; i < SIZE; i++) {
+ for (int i = 0; i < DATASET_SIZE; i++) {
mDatabase.delete("t1", null, null);
}
}
@@ -718,17 +660,13 @@
* 100 Deletes
*/
public static class Delete100 extends PerformanceBase {
- private static final int SIZE = SIZE_MULTIPLIER;
-
@Override
- public void setUp() {
- super.setUp();
+ protected void prepareForTest() {
Random random = new Random(42);
- mDatabase
- .execSQL("CREATE TABLE t1(a INTEGER, b INTEGER, c VARCHAR(100))");
+ mDatabase.execSQL("CREATE TABLE t1(a INTEGER, b INTEGER, c VARCHAR(100))");
- for (int i = 0; i < SIZE; i++) {
+ for (int i = 0; i < DATASET_SIZE; i++) {
int r = random.nextInt(100000);
mDatabase.execSQL("INSERT INTO t1 VALUES(" + i + "," + r + ",'"
+ numberName(r) + "')");
@@ -737,7 +675,7 @@
}
public void testRun() {
- for (int i = 0; i < SIZE; i++) {
+ for (int i = 0; i < DATASET_SIZE; i++) {
mDatabase.delete("t1", null, null);
}
}
@@ -747,33 +685,30 @@
* 100 DELETE's without an index with where clause
*/
public static class DeleteWhere100 extends PerformanceBase {
- private static final int SIZE = SIZE_MULTIPLIER;
- private String[] where = new String[SIZE];
+ private String[] mWhere = new String[DATASET_SIZE];
@Override
- public void setUp() {
- super.setUp();
+ protected void prepareForTest() {
Random random = new Random(42);
- mDatabase
- .execSQL("CREATE TABLE t1(a INTEGER, b INTEGER, c VARCHAR(100))");
+ mDatabase.execSQL("CREATE TABLE t1(a INTEGER, b INTEGER, c VARCHAR(100))");
- for (int i = 0; i < SIZE; i++) {
+ for (int i = 0; i < DATASET_SIZE; i++) {
int r = random.nextInt(100000);
mDatabase.execSQL("INSERT INTO t1 VALUES(" + i + "," + r + ",'"
+ numberName(r) + "')");
}
- for (int i = 0; i < SIZE; i++) {
+ for (int i = 0; i < DATASET_SIZE; i++) {
int lower = i * 100;
int upper = (i + 10) * 100;
- where[i] = "b >= " + lower + " AND b < " + upper;
+ mWhere[i] = "b >= " + lower + " AND b < " + upper;
}
}
public void testRun() {
- for (int i = 0; i < SIZE; i++) {
- mDatabase.delete("t1", where[i], null);
+ for (int i = 0; i < DATASET_SIZE; i++) {
+ mDatabase.delete("t1", mWhere[i], null);
}
}
}
@@ -782,34 +717,31 @@
* 100 DELETE's with an index with where clause
*/
public static class DeleteIndexWhere100 extends PerformanceBase {
- private static final int SIZE = SIZE_MULTIPLIER;
- private String[] where = new String[SIZE];
+ private String[] mWhere = new String[DATASET_SIZE];
@Override
- public void setUp() {
- super.setUp();
+ protected void prepareForTest() {
Random random = new Random(42);
- mDatabase
- .execSQL("CREATE TABLE t1(a INTEGER, b INTEGER, c VARCHAR(100))");
+ mDatabase.execSQL("CREATE TABLE t1(a INTEGER, b INTEGER, c VARCHAR(100))");
mDatabase.execSQL("CREATE INDEX i1b ON t1(b)");
- for (int i = 0; i < SIZE; i++) {
+ for (int i = 0; i < DATASET_SIZE; i++) {
int r = random.nextInt(100000);
mDatabase.execSQL("INSERT INTO t1 VALUES(" + i + "," + r + ",'"
+ numberName(r) + "')");
}
- for (int i = 0; i < SIZE; i++) {
+ for (int i = 0; i < DATASET_SIZE; i++) {
int lower = i * 100;
int upper = (i + 10) * 100;
- where[i] = "b >= " + lower + " AND b < " + upper;
+ mWhere[i] = "b >= " + lower + " AND b < " + upper;
}
}
public void testRun() {
- for (int i = 0; i < SIZE; i++) {
- mDatabase.delete("t1", where[i], null);
+ for (int i = 0; i < DATASET_SIZE; i++) {
+ mDatabase.delete("t1", mWhere[i], null);
}
}
}
@@ -818,30 +750,26 @@
* 100 update's with an index with where clause
*/
public static class UpdateIndexWhere100 extends PerformanceBase {
- private static final int SIZE = SIZE_MULTIPLIER;
- private String[] where = new String[SIZE];
- ContentValues[] mValues = new ContentValues[SIZE];
+ private String[] mWhere = new String[DATASET_SIZE];
+ ContentValues[] mValues = new ContentValues[DATASET_SIZE];
@Override
- public void setUp() {
- super.setUp();
+ protected void prepareForTest() {
Random random = new Random(42);
- mDatabase
- .execSQL("CREATE TABLE t1(a INTEGER, b INTEGER, c VARCHAR(100))");
+ mDatabase.execSQL("CREATE TABLE t1(a INTEGER, b INTEGER, c VARCHAR(100))");
mDatabase.execSQL("CREATE INDEX i1b ON t1(b)");
- for (int i = 0; i < SIZE; i++) {
+ for (int i = 0; i < DATASET_SIZE; i++) {
int r = random.nextInt(100000);
mDatabase.execSQL("INSERT INTO t1 VALUES(" + i + "," + r + ",'"
+ numberName(r) + "')");
}
- for (int i = 0; i < SIZE; i++) {
-
+ for (int i = 0; i < DATASET_SIZE; i++) {
int lower = i * 100;
int upper = (i + 10) * 100;
- where[i] = "b >= " + lower + " AND b < " + upper;
+ mWhere[i] = "b >= " + lower + " AND b < " + upper;
ContentValues b = new ContentValues(1);
b.put("b", upper);
mValues[i] = b;
@@ -850,8 +778,8 @@
}
public void testRun() {
- for (int i = 0; i < SIZE; i++) {
- mDatabase.update("t1", mValues[i], where[i], null);
+ for (int i = 0; i < DATASET_SIZE; i++) {
+ mDatabase.update("t1", mValues[i], mWhere[i], null);
}
}
}
@@ -860,29 +788,26 @@
* 100 update's without an index with where clause
*/
public static class UpdateWhere100 extends PerformanceBase {
- private static final int SIZE = SIZE_MULTIPLIER;
- private String[] where = new String[SIZE];
- ContentValues[] mValues = new ContentValues[SIZE];
+ private String[] mWhere = new String[DATASET_SIZE];
+ ContentValues[] mValues = new ContentValues[DATASET_SIZE];
@Override
- public void setUp() {
- super.setUp();
+ protected void prepareForTest() {
Random random = new Random(42);
- mDatabase
- .execSQL("CREATE TABLE t1(a INTEGER, b INTEGER, c VARCHAR(100))");
+ mDatabase.execSQL("CREATE TABLE t1(a INTEGER, b INTEGER, c VARCHAR(100))");
- for (int i = 0; i < SIZE; i++) {
+ for (int i = 0; i < DATASET_SIZE; i++) {
int r = random.nextInt(100000);
mDatabase.execSQL("INSERT INTO t1 VALUES(" + i + "," + r + ",'"
+ numberName(r) + "')");
}
- for (int i = 0; i < SIZE; i++) {
+ for (int i = 0; i < DATASET_SIZE; i++) {
int lower = i * 100;
int upper = (i + 10) * 100;
- where[i] = "b >= " + lower + " AND b < " + upper;
+ mWhere[i] = "b >= " + lower + " AND b < " + upper;
ContentValues b = new ContentValues(1);
b.put("b", upper);
mValues[i] = b;
@@ -890,8 +815,8 @@
}
public void testRun() {
- for (int i = 0; i < SIZE; i++) {
- mDatabase.update("t1", mValues[i], where[i], null);
+ for (int i = 0; i < DATASET_SIZE; i++) {
+ mDatabase.update("t1", mValues[i], mWhere[i], null);
}
}
}
@@ -900,36 +825,31 @@
* 100 selects for a String - contains 'e'
*/
public static class SelectStringContains100 extends PerformanceBase {
- private static final int SIZE = SIZE_MULTIPLIER;
- private static final int REPEAT_COUNT = 10;
private static final String[] COLUMNS = {"t3.a"};
- private String[] where = new String[SIZE];
+ private String[] mWhere = new String[DATASET_SIZE];
@Override
- public void setUp() {
- super.setUp();
+ protected void prepareForTest() {
Random random = new Random(42);
- mDatabase
- .execSQL("CREATE TABLE t3(a VARCHAR(100))");
+ mDatabase.execSQL("CREATE TABLE t3(a VARCHAR(100))");
- for (int i = 0; i < SIZE; i++) {
+ for (int i = 0; i < DATASET_SIZE; i++) {
int r = random.nextInt(100000);
mDatabase.execSQL("INSERT INTO t3 VALUES('"
+ numberName(r) + "')");
}
- for (int i = 0; i < SIZE; i++) {
- where[i] = "a LIKE '*e*'";
+ for (int i = 0; i < DATASET_SIZE; i++) {
+ mWhere[i] = "a LIKE '*e*'";
}
}
public void testRun() {
- for (int iter = 0; iter < REPEAT_COUNT; iter++) {
- for (int i = 0; i < SIZE; i++) {
- mDatabase.query("t3", COLUMNS, where[i], null, null, null, null);
- }
+ for (int i = 0; i < FAST_OP_COUNT; i++) {
+ checkCursor(mDatabase
+ .query("t3", COLUMNS, mWhere[i % DATASET_SIZE], null, null, null, null));
}
}
}
@@ -938,37 +858,32 @@
* 100 selects for a String - contains 'e'-indexed table
*/
public static class SelectStringIndexedContains100 extends PerformanceBase {
- private static final int SIZE = SIZE_MULTIPLIER;
- private static final int REPEAT_COUNT = 10;
private static final String[] COLUMNS = {"t3.a"};
- private String[] where = new String[SIZE];
+ private String[] mWhere = new String[DATASET_SIZE];
@Override
- public void setUp() {
- super.setUp();
+ protected void prepareForTest() {
Random random = new Random(42);
- mDatabase
- .execSQL("CREATE TABLE t3(a VARCHAR(100))");
+ mDatabase.execSQL("CREATE TABLE t3(a VARCHAR(100))");
mDatabase.execSQL("CREATE INDEX i3a ON t3(a)");
- for (int i = 0; i < SIZE; i++) {
+ for (int i = 0; i < DATASET_SIZE; i++) {
int r = random.nextInt(100000);
mDatabase.execSQL("INSERT INTO t3 VALUES('"
+ numberName(r) + "')");
}
- for (int i = 0; i < SIZE; i++) {
- where[i] = "a LIKE '*e*'";
+ for (int i = 0; i < DATASET_SIZE; i++) {
+ mWhere[i] = "a LIKE '*e*'";
}
}
public void testRun() {
- for (int iter = 0; iter < REPEAT_COUNT; iter++) {
- for (int i = 0; i < SIZE; i++) {
- mDatabase.query("t3", COLUMNS, where[i], null, null, null, null);
- }
+ for (int i = 0; i < FAST_OP_COUNT; i++) {
+ checkCursor(mDatabase
+ .query("t3", COLUMNS, mWhere[i % DATASET_SIZE], null, null, null, null));
}
}
}
diff --git a/core/tests/coretests/src/android/database/run_newdb_perf_test.sh b/core/tests/coretests/src/android/database/run_newdb_perf_test.sh
index 10a62e6..c5b2c97 100755
--- a/core/tests/coretests/src/android/database/run_newdb_perf_test.sh
+++ b/core/tests/coretests/src/android/database/run_newdb_perf_test.sh
@@ -17,8 +17,11 @@
adb install -r -g ${ANDROID_PRODUCT_OUT}/data/app/FrameworksCoreTests/FrameworksCoreTests.apk
adb logcat -c
-echo "Running benchmark 5 times"
-for i in {1..5}
+# by default run 5 times
+RUN_N=${1:-5}
+echo "Running benchmark $RUN_N times"
+
+for (( i=0; i<$RUN_N; i++ ))
do
adb shell am instrument -e class 'android.database.NewDatabasePerformanceTestSuite' -w 'com.android.frameworks.coretests/android.support.test.runner.AndroidJUnitRunner'
done
diff --git a/core/tests/coretests/src/android/net/LinkPropertiesTest.java b/core/tests/coretests/src/android/net/LinkPropertiesTest.java
index d5f6321..9686dd9 100644
--- a/core/tests/coretests/src/android/net/LinkPropertiesTest.java
+++ b/core/tests/coretests/src/android/net/LinkPropertiesTest.java
@@ -24,10 +24,15 @@
import android.system.OsConstants;
import android.test.suitebuilder.annotation.SmallTest;
import android.test.suitebuilder.annotation.Suppress;
+import android.util.ArraySet;
+
import junit.framework.TestCase;
import java.net.InetAddress;
-import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Set;
public class LinkPropertiesTest extends TestCase {
@@ -678,4 +683,76 @@
stacked.addRoute(new RouteInfo((IpPrefix) null, stackedAddress));
assertTrue(v6lp.isReachable(DNS1));
}
+
+ @SmallTest
+ public void testLinkPropertiesEnsureDirectlyConnectedRoutes() {
+ // IPv4 case: no route added initially
+ LinkProperties rmnet0 = new LinkProperties();
+ rmnet0.setInterfaceName("rmnet0");
+ rmnet0.addLinkAddress(new LinkAddress("10.0.0.2/8"));
+ RouteInfo directRoute0 = new RouteInfo(new IpPrefix("10.0.0.0/8"), null,
+ rmnet0.getInterfaceName());
+
+ // Since no routes is added explicitly, getAllRoutes() should return empty.
+ assertTrue(rmnet0.getAllRoutes().isEmpty());
+ rmnet0.ensureDirectlyConnectedRoutes();
+ // ensureDirectlyConnectedRoutes() should have added the missing local route.
+ assertEqualRoutes(Collections.singletonList(directRoute0), rmnet0.getAllRoutes());
+
+ // IPv4 case: both direct and default routes added initially
+ LinkProperties rmnet1 = new LinkProperties();
+ rmnet1.setInterfaceName("rmnet1");
+ rmnet1.addLinkAddress(new LinkAddress("10.0.0.3/8"));
+ RouteInfo defaultRoute1 = new RouteInfo((IpPrefix) null,
+ NetworkUtils.numericToInetAddress("10.0.0.1"), rmnet1.getInterfaceName());
+ RouteInfo directRoute1 = new RouteInfo(new IpPrefix("10.0.0.0/8"), null,
+ rmnet1.getInterfaceName());
+ rmnet1.addRoute(defaultRoute1);
+ rmnet1.addRoute(directRoute1);
+
+ // Check added routes
+ assertEqualRoutes(Arrays.asList(defaultRoute1, directRoute1), rmnet1.getAllRoutes());
+ // ensureDirectlyConnectedRoutes() shouldn't change the routes since direct connected
+ // route is already part of the configuration.
+ rmnet1.ensureDirectlyConnectedRoutes();
+ assertEqualRoutes(Arrays.asList(defaultRoute1, directRoute1), rmnet1.getAllRoutes());
+
+ // IPv6 case: only default routes added initially
+ LinkProperties rmnet2 = new LinkProperties();
+ rmnet2.setInterfaceName("rmnet2");
+ rmnet2.addLinkAddress(new LinkAddress("fe80::cafe/64"));
+ rmnet2.addLinkAddress(new LinkAddress("2001:db8::2/64"));
+ RouteInfo defaultRoute2 = new RouteInfo((IpPrefix) null,
+ NetworkUtils.numericToInetAddress("2001:db8::1"), rmnet2.getInterfaceName());
+ RouteInfo directRoute2 = new RouteInfo(new IpPrefix("2001:db8::/64"), null,
+ rmnet2.getInterfaceName());
+ RouteInfo linkLocalRoute2 = new RouteInfo(new IpPrefix("fe80::/64"), null,
+ rmnet2.getInterfaceName());
+ rmnet2.addRoute(defaultRoute2);
+
+ assertEqualRoutes(Arrays.asList(defaultRoute2), rmnet2.getAllRoutes());
+ rmnet2.ensureDirectlyConnectedRoutes();
+ assertEqualRoutes(Arrays.asList(defaultRoute2, directRoute2, linkLocalRoute2),
+ rmnet2.getAllRoutes());
+
+ // Corner case: no interface name
+ LinkProperties rmnet3 = new LinkProperties();
+ rmnet3.addLinkAddress(new LinkAddress("192.168.0.2/24"));
+ RouteInfo directRoute3 = new RouteInfo(new IpPrefix("192.168.0.0/24"), null,
+ rmnet3.getInterfaceName());
+
+ assertTrue(rmnet3.getAllRoutes().isEmpty());
+ rmnet3.ensureDirectlyConnectedRoutes();
+ assertEqualRoutes(Collections.singletonList(directRoute3), rmnet3.getAllRoutes());
+
+ }
+
+ private void assertEqualRoutes(Collection<RouteInfo> expected, Collection<RouteInfo> actual) {
+ Set<RouteInfo> expectedSet = new ArraySet<>(expected);
+ Set<RouteInfo> actualSet = new ArraySet<>(actual);
+ // Duplicated entries in actual routes are considered failures
+ assertEquals(actual.size(), actualSet.size());
+
+ assertEquals(expectedSet, actualSet);
+ }
}
diff --git a/media/jni/android_media_MediaCodec.cpp b/media/jni/android_media_MediaCodec.cpp
index 2d008c7..022198b 100644
--- a/media/jni/android_media_MediaCodec.cpp
+++ b/media/jni/android_media_MediaCodec.cpp
@@ -137,7 +137,7 @@
mLooper->start(
false, // runOnCallingThread
true, // canCallJava
- PRIORITY_FOREGROUND);
+ ANDROID_PRIORITY_VIDEO);
if (nameIsType) {
mCodec = MediaCodec::CreateByType(mLooper, name, encoder, &mInitStatus);
diff --git a/packages/EasterEgg/AndroidManifest.xml b/packages/EasterEgg/AndroidManifest.xml
index 14861c26..172490d 100644
--- a/packages/EasterEgg/AndroidManifest.xml
+++ b/packages/EasterEgg/AndroidManifest.xml
@@ -84,5 +84,16 @@
<action android:name="android.service.quicksettings.action.QS_TILE" />
</intent-filter>
</service>
+
+ <!-- FileProvider for sending pictures -->
+ <provider
+ android:name="android.support.v4.content.FileProvider"
+ android:authorities="com.android.egg.fileprovider"
+ android:grantUriPermissions="true"
+ android:exported="false">
+ <meta-data
+ android:name="android.support.FILE_PROVIDER_PATHS"
+ android:resource="@xml/filepaths" />
+ </provider>
</application>
</manifest>
diff --git a/packages/EasterEgg/res/drawable/food_cookie.xml b/packages/EasterEgg/res/drawable/food_cookie.xml
new file mode 100644
index 0000000..74dd134
--- /dev/null
+++ b/packages/EasterEgg/res/drawable/food_cookie.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Copyright (C) 2017 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+ <group>
+ <path
+ android:fillColor="#55FFFFFF"
+ android:fillType="evenOdd"
+ android:pathData="M5.71 18.29A8.99 8.99 0 0 0 22 13c0-3-1.46-5.65-3.71-7.29A8.99 8.99 0 0 0 2 11c0 3 1.46 5.65 3.71 7.29z"/>
+ <path
+ android:fillColor="#FFFFFFFF"
+ android:fillType="evenOdd"
+ android:pathData="M7.25 19.18A8.5 8.5 0 0 0 19.19 7.24 9 9 0 0 1 7.24 19.19z"/>
+ <path
+ android:fillColor="#55FFFFFF"
+ android:pathData="M10.5 3a0.5 0.5 0 1 1 1 0v2.05a0.5 0.5 0 1 1-1 0V3zm3.1 0.42a0.5 0.5 0 0 1 0.93 0.39l-0.8 1.88A0.5 0.5 0 1 1 12.8 5.3l0.8-1.88zm2.7 1.57a0.5 0.5 0 1 1 0.71 0.7l-1.45 1.46a0.5 0.5 0 0 1-0.7-0.71l1.44-1.45zm1.9 2.5a0.5 0.5 0 0 1 0.38 0.92l-1.9 0.77a0.5 0.5 0 0 1-0.37-0.93l1.9-0.77zM19 10.5a0.5 0.5 0 1 1 0 1h-2.05a0.5 0.5 0 0 1 0-1H19zm-0.42 3.1a0.5 0.5 0 0 1-0.39 0.93l-1.88-0.8a0.5 0.5 0 1 1 0.39-0.92l1.88 0.8zm-1.57 2.7a0.5 0.5 0 1 1-0.7 0.71l-1.46-1.45a0.5 0.5 0 0 1 0.71-0.7l1.45 1.44zm-2.5 1.9a0.5 0.5 0 1 1-0.92 0.38l-0.77-1.9a0.5 0.5 0 0 1 0.93-0.37l0.77 1.9zM11.5 19a0.5 0.5 0 1 1-1 0v-2.05a0.5 0.5 0 0 1 1 0V19zm-3.1-0.42a0.5 0.5 0 0 1-0.93-0.39l0.8-1.88A0.5 0.5 0 0 1 9.2 16.7l-0.8 1.88zm-2.7-1.57a0.5 0.5 0 1 1-0.71-0.7l1.45-1.46a0.5 0.5 0 0 1 0.7 0.71L5.7 17.01zm-1.9-2.48a0.5 0.5 0 0 1-0.38-0.92l1.88-0.8a0.5 0.5 0 0 1 0.4 0.92l-1.9 0.8zM3 11.5a0.5 0.5 0 1 1 0-1h2.05a0.5 0.5 0 1 1 0 1H3zm0.42-3.1A0.5 0.5 0 0 1 3.8 7.46l1.88 0.8A0.5 0.5 0 1 1 5.3 9.2L3.42 8.4zm1.57-2.7a0.5 0.5 0 1 1 0.7-0.71l1.46 1.45a0.5 0.5 0 0 1-0.71 0.7L4.99 5.7zm2.5-1.9A0.5 0.5 0 0 1 8.4 3.41l0.77 1.9a0.5 0.5 0 0 1-0.93 0.37L7.48 3.8z"/>
+ </group>
+</vector>
\ No newline at end of file
diff --git a/packages/EasterEgg/res/values/strings.xml b/packages/EasterEgg/res/values/strings.xml
index 8478a43..61e3834 100644
--- a/packages/EasterEgg/res/values/strings.xml
+++ b/packages/EasterEgg/res/values/strings.xml
@@ -17,6 +17,7 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android">
<string name="app_name" translatable="false">Android Easter Egg</string>
<string name="notification_name" translatable="false">Android Neko</string>
+ <string name="notification_channel_name" translatable="false">New cats</string>
<string name="default_tile_name" translatable="false">\????</string>
<string name="notification_title" translatable="false">A cat is here.</string>
<string name="default_cat_name" translatable="false">Cat #%s</string>
@@ -34,7 +35,7 @@
<item>@drawable/food_bits</item>
<item>@drawable/food_sysuituna</item>
<item>@drawable/food_chicken</item>
- <item>@drawable/food_donut</item>
+ <item>@drawable/food_cookie</item>
</array>
<integer-array name="food_intervals">
<item>0</item>
diff --git a/packages/EasterEgg/res/xml/filepaths.xml b/packages/EasterEgg/res/xml/filepaths.xml
new file mode 100644
index 0000000..2130025
--- /dev/null
+++ b/packages/EasterEgg/res/xml/filepaths.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Copyright (C) 2017 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.
+-->
+<paths>
+ <external-path name="cats" path="Pictures/Cats" />
+</paths>
\ No newline at end of file
diff --git a/packages/EasterEgg/src/com/android/egg/neko/Cat.java b/packages/EasterEgg/src/com/android/egg/neko/Cat.java
index a4df372..dd1bd07 100644
--- a/packages/EasterEgg/src/com/android/egg/neko/Cat.java
+++ b/packages/EasterEgg/src/com/android/egg/neko/Cat.java
@@ -31,6 +31,8 @@
import com.android.egg.R;
import com.android.internal.logging.MetricsLogger;
+import static com.android.egg.neko.NekoLand.CHAN_ID;
+
public class Cat extends Drawable {
public static final long[] PURR = {0, 40, 20, 40, 20, 40, 20, 40, 20, 40, 20, 40};
@@ -218,6 +220,7 @@
.setContentText(getName())
.setContentIntent(PendingIntent.getActivity(context, 0, intent, 0))
.setAutoCancel(true)
+ .setChannel(CHAN_ID)
.setVibrate(PURR)
.addExtras(extras);
}
diff --git a/packages/EasterEgg/src/com/android/egg/neko/NekoLand.java b/packages/EasterEgg/src/com/android/egg/neko/NekoLand.java
index 689e381..d2e37d8 100644
--- a/packages/EasterEgg/src/com/android/egg/neko/NekoLand.java
+++ b/packages/EasterEgg/src/com/android/egg/neko/NekoLand.java
@@ -31,6 +31,7 @@
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore.Images;
+import android.support.v4.content.FileProvider;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
@@ -56,6 +57,8 @@
import java.util.List;
public class NekoLand extends Activity implements PrefsListener {
+ public static String CHAN_ID = "EGG";
+
public static boolean DEBUG = false;
public static boolean DEBUG_NOTIFICATIONS = false;
@@ -289,10 +292,13 @@
new String[] {png.toString()},
new String[] {"image/png"},
null);
- Uri uri = Uri.fromFile(png);
+ Log.v("Neko", "cat file: " + png);
+ Uri uri = FileProvider.getUriForFile(this, "com.android.egg.fileprovider", png);
+ Log.v("Neko", "cat uri: " + uri);
Intent intent = new Intent(Intent.ACTION_SEND);
intent.putExtra(Intent.EXTRA_STREAM, uri);
intent.putExtra(Intent.EXTRA_SUBJECT, cat.getName());
+ intent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
intent.setType("image/png");
startActivity(Intent.createChooser(intent, null));
cat.logShare(this);
diff --git a/packages/EasterEgg/src/com/android/egg/neko/NekoService.java b/packages/EasterEgg/src/com/android/egg/neko/NekoService.java
index 808ec36..42506e6 100644
--- a/packages/EasterEgg/src/com/android/egg/neko/NekoService.java
+++ b/packages/EasterEgg/src/com/android/egg/neko/NekoService.java
@@ -15,15 +15,15 @@
package com.android.egg.neko;
import android.app.Notification;
+import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.job.JobInfo;
import android.app.job.JobParameters;
import android.app.job.JobScheduler;
import android.app.job.JobService;
-import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
-import android.content.Intent;
+import android.net.Uri;
import android.os.Bundle;
import java.util.List;
@@ -33,6 +33,9 @@
import java.util.Random;
+import static com.android.egg.neko.Cat.PURR;
+import static com.android.egg.neko.NekoLand.CHAN_ID;
+
public class NekoService extends JobService {
private static final String TAG = "NekoService";
@@ -40,6 +43,7 @@
public static int JOB_ID = 42;
public static int CAT_NOTIFICATION = 1;
+ public static int DEBUG_NOTIFICATION = 1234;
public static float CAT_CAPTURE_PROB = 1.0f; // generous
@@ -50,6 +54,18 @@
public static float INTERVAL_JITTER_FRAC = 0.25f;
+ private static void setupNotificationChannels(Context context) {
+ NotificationManager noman = context.getSystemService(NotificationManager.class);
+ NotificationChannel eggChan = new NotificationChannel(CHAN_ID,
+ context.getString(R.string.notification_channel_name),
+ NotificationManager.IMPORTANCE_DEFAULT);
+ eggChan.setSound(Uri.EMPTY, Notification.AUDIO_ATTRIBUTES_DEFAULT); // cats are quiet
+ eggChan.setVibrationPattern(PURR); // not totally quiet though
+ eggChan.setBlockableSystem(true); // unlike a real cat, you can push this one off your lap
+ eggChan.setLockscreenVisibility(Notification.VISIBILITY_PUBLIC); // cats sit in the window
+ noman.createNotificationChannel(eggChan);
+ }
+
@Override
public boolean onStartJob(JobParameters params) {
Log.v(TAG, "Starting job: " + String.valueOf(params));
@@ -64,8 +80,9 @@
final Notification.Builder builder
= cat.buildNotification(this)
.setContentTitle("DEBUG")
+ .setChannel(NekoLand.CHAN_ID)
.setContentText("Ran job: " + params);
- noman.notify(1, builder.build());
+ noman.notify(DEBUG_NOTIFICATION, builder.build());
}
final PrefState prefs = new PrefState(this);
@@ -111,6 +128,8 @@
}
public static void registerJob(Context context, long intervalMinutes) {
+ setupNotificationChannels(context);
+
JobScheduler jss = context.getSystemService(JobScheduler.class);
jss.cancel(JOB_ID);
long interval = intervalMinutes * MINUTES;
@@ -126,12 +145,13 @@
if (NekoLand.DEBUG_NOTIFICATIONS) {
NotificationManager noman = context.getSystemService(NotificationManager.class);
- noman.notify(500, new Notification.Builder(context)
+ noman.notify(DEBUG_NOTIFICATION, new Notification.Builder(context)
.setSmallIcon(R.drawable.stat_icon)
.setContentTitle(String.format("Job scheduled in %d min", (interval / MINUTES)))
.setContentText(String.valueOf(jobInfo))
.setPriority(Notification.PRIORITY_MIN)
.setCategory(Notification.CATEGORY_SERVICE)
+ .setChannel(NekoLand.CHAN_ID)
.setShowWhen(true)
.build());
}
diff --git a/packages/SettingsLib/src/com/android/settingslib/drawer/TileUtils.java b/packages/SettingsLib/src/com/android/settingslib/drawer/TileUtils.java
index 9620a91..3c095ae 100644
--- a/packages/SettingsLib/src/com/android/settingslib/drawer/TileUtils.java
+++ b/packages/SettingsLib/src/com/android/settingslib/drawer/TileUtils.java
@@ -442,15 +442,6 @@
if (metaData.containsKey(META_DATA_PREFERENCE_CUSTOM_VIEW)) {
int layoutId = metaData.getInt(META_DATA_PREFERENCE_CUSTOM_VIEW);
remoteViews = new RemoteViews(applicationInfo.packageName, layoutId);
- if (metaData.containsKey(META_DATA_PREFERENCE_SUMMARY_URI)) {
- String uriString = metaData.getString(
- META_DATA_PREFERENCE_SUMMARY_URI);
- String overrideSummary = getTextFromUri(context, uriString, providerMap,
- META_DATA_PREFERENCE_SUMMARY);
- if (overrideSummary != null) {
- remoteViews.setTextViewText(android.R.id.summary, overrideSummary);
- }
- }
}
}
} catch (PackageManager.NameNotFoundException | Resources.NotFoundException e) {
@@ -555,6 +546,30 @@
}
}
+ public static void updateTileUsingSummaryUri(Context context, Tile tile) {
+ if (tile == null || tile.metaData == null ||
+ !tile.metaData.containsKey(META_DATA_PREFERENCE_SUMMARY_URI)) {
+ return;
+ }
+
+ final Map<String, IContentProvider> providerMap = new HashMap<>();
+
+ final String uriString = tile.metaData.getString(META_DATA_PREFERENCE_SUMMARY_URI);
+ final Bundle bundle = getBundleFromUri(context, uriString, providerMap);
+ final String overrideSummary = getString(bundle, META_DATA_PREFERENCE_SUMMARY);
+ final String overrideTitle = getString(bundle, META_DATA_PREFERENCE_TITLE);
+ if (overrideSummary != null) {
+ tile.remoteViews.setTextViewText(android.R.id.summary, overrideSummary);
+ }
+ if (overrideTitle != null) {
+ tile.remoteViews.setTextViewText(android.R.id.title, overrideTitle);
+ }
+ }
+
+ private static String getString(Bundle bundle, String key) {
+ return bundle == null ? null : bundle.getString(key);
+ }
+
private static IContentProvider getProviderFromUri(Context context, Uri uri,
Map<String, IContentProvider> providerMap) {
if (uri == null) {
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/drawer/TileUtilsTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/drawer/TileUtilsTest.java
index e9ca753..7e7fdb2 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/drawer/TileUtilsTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/drawer/TileUtilsTest.java
@@ -22,10 +22,12 @@
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.argThat;
-import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.ArgumentMatchers.isNull;
+import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.atLeastOnce;
+import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import static org.robolectric.RuntimeEnvironment.application;
@@ -64,9 +66,6 @@
import org.mockito.MockitoAnnotations;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
-import org.robolectric.annotation.Implementation;
-import org.robolectric.annotation.Implements;
-import org.robolectric.internal.ShadowExtractor;
import java.util.ArrayList;
import java.util.Collections;
@@ -75,8 +74,7 @@
@RunWith(RobolectricTestRunner.class)
@Config(manifest = TestConfig.MANIFEST_PATH,
- sdk = TestConfig.SDK_VERSION,
- shadows = {TileUtilsTest.TileUtilsShadowRemoteViews.class})
+ sdk = TestConfig.SDK_VERSION)
public class TileUtilsTest {
@Mock
@@ -421,24 +419,12 @@
}
@Test
- public void getTilesForIntent_summaryUriSpecified_shouldOverrideRemoteViewSummary()
+ public void updateTileUsingSummaryUri_summaryUriSpecified_shouldOverrideRemoteViewSummary()
throws RemoteException {
- Intent intent = new Intent();
- Map<Pair<String, String>, Tile> addedCache = new ArrayMap<>();
- List<Tile> outTiles = new ArrayList<>();
- List<ResolveInfo> info = new ArrayList<>();
- ResolveInfo resolveInfo = newInfo(true, null /* category */, null,
- null, URI_GET_SUMMARY);
- resolveInfo.activityInfo.metaData.putInt("com.android.settings.custom_view",
- R.layout.user_preference);
- info.add(resolveInfo);
-
- when(mPackageManager.queryIntentActivitiesAsUser(eq(intent), anyInt(), anyInt()))
- .thenReturn(info);
-
// Mock the content provider interaction.
Bundle bundle = new Bundle();
- bundle.putString(TileUtils.META_DATA_PREFERENCE_SUMMARY, "new summary text");
+ String expectedSummary = "new summary text";
+ bundle.putString(TileUtils.META_DATA_PREFERENCE_SUMMARY, expectedSummary);
when(mIContentProvider.call(anyString(),
eq(TileUtils.getMethodFromUri(Uri.parse(URI_GET_SUMMARY))), eq(URI_GET_SUMMARY),
any())).thenReturn(bundle);
@@ -447,57 +433,12 @@
when(mContentResolver.acquireUnstableProvider(any(Uri.class)))
.thenReturn(mIContentProvider);
- TileUtils.getTilesForIntent(mContext, UserHandle.CURRENT, intent, addedCache,
- null /* defaultCategory */, outTiles, false /* usePriority */,
- false /* checkCategory */, true /* forceTintExternalIcon */);
-
- assertThat(outTiles.size()).isEqualTo(1);
- Tile tile = outTiles.get(0);
- assertThat(tile.remoteViews).isNotNull();
- assertThat(tile.remoteViews.getLayoutId()).isEqualTo(R.layout.user_preference);
- // Make sure the summary TextView got a new text string.
- TileUtilsShadowRemoteViews shadowRemoteViews =
- (TileUtilsShadowRemoteViews) ShadowExtractor.extract(tile.remoteViews);
- assertThat(shadowRemoteViews.overrideViewId).isEqualTo(android.R.id.summary);
- assertThat(shadowRemoteViews.overrideText).isEqualTo("new summary text");
- }
-
- @Test
- public void getTilesForIntent_providerUnavailable_shouldNotOverrideRemoteViewSummary()
- throws RemoteException {
- Intent intent = new Intent();
- Map<Pair<String, String>, Tile> addedCache = new ArrayMap<>();
- List<Tile> outTiles = new ArrayList<>();
- List<ResolveInfo> info = new ArrayList<>();
- ResolveInfo resolveInfo = newInfo(true, null /* category */, null,
- null, URI_GET_SUMMARY);
- resolveInfo.activityInfo.metaData.putInt("com.android.settings.custom_view",
- R.layout.user_preference);
- info.add(resolveInfo);
-
- when(mPackageManager.queryIntentActivitiesAsUser(eq(intent), anyInt(), anyInt()))
- .thenReturn(info);
-
- // Mock the content provider interaction.
- Bundle bundle = new Bundle();
- bundle.putString(TileUtils.META_DATA_PREFERENCE_SUMMARY, "new summary text");
- when(mIContentProvider.call(anyString(),
- eq(TileUtils.getMethodFromUri(Uri.parse(URI_GET_SUMMARY))), eq(URI_GET_SUMMARY),
- any())).thenReturn(bundle);
-
- TileUtils.getTilesForIntent(mContext, UserHandle.CURRENT, intent, addedCache,
- null /* defaultCategory */, outTiles, false /* usePriority */,
- false /* checkCategory */, true /* forceTintExternalIcon */);
-
- assertThat(outTiles.size()).isEqualTo(1);
- Tile tile = outTiles.get(0);
- assertThat(tile.remoteViews).isNotNull();
- assertThat(tile.remoteViews.getLayoutId()).isEqualTo(R.layout.user_preference);
- // Make sure the summary TextView didn't get any text view updates.
- TileUtilsShadowRemoteViews shadowRemoteViews =
- (TileUtilsShadowRemoteViews) ShadowExtractor.extract(tile.remoteViews);
- assertThat(shadowRemoteViews.overrideViewId).isNull();
- assertThat(shadowRemoteViews.overrideText).isNull();
+ Tile tile = new Tile();
+ tile.metaData = new Bundle();
+ tile.metaData.putString(TileUtils.META_DATA_PREFERENCE_SUMMARY_URI, URI_GET_SUMMARY);
+ tile.remoteViews = mock(RemoteViews.class);
+ TileUtils.updateTileUsingSummaryUri(mContext, tile);
+ verify(tile.remoteViews, times(1)).setTextViewText(anyInt(), eq(expectedSummary));
}
public static ResolveInfo newInfo(boolean systemApp, String category) {
@@ -562,16 +503,4 @@
}
}
- @Implements(RemoteViews.class)
- public static class TileUtilsShadowRemoteViews {
-
- private Integer overrideViewId;
- private CharSequence overrideText;
-
- @Implementation
- public void setTextViewText(int viewId, CharSequence text) {
- overrideViewId = viewId;
- overrideText = text;
- }
- }
}
diff --git a/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml
index c997160..070634b 100644
--- a/packages/SystemUI/AndroidManifest.xml
+++ b/packages/SystemUI/AndroidManifest.xml
@@ -318,15 +318,20 @@
android:exported="false">
</activity>
+ <!-- Springboard for launching the share activity -->
+ <receiver android:name=".screenshot.GlobalScreenshot$ShareReceiver"
+ android:process=":screenshot"
+ android:exported="false" />
+
<!-- Callback for dismissing screenshot notification after a share target is picked -->
<receiver android:name=".screenshot.GlobalScreenshot$TargetChosenReceiver"
- android:process=":screenshot"
- android:exported="false" />
+ android:process=":screenshot"
+ android:exported="false" />
<!-- Callback for deleting screenshot notification -->
<receiver android:name=".screenshot.GlobalScreenshot$DeleteScreenshotReceiver"
- android:process=":screenshot"
- android:exported="false" />
+ android:process=":screenshot"
+ android:exported="false" />
<!-- started from UsbDeviceSettingsManager -->
<activity android:name=".usb.UsbConfirmActivity"
diff --git a/packages/SystemUI/res/layout/car_fullscreen_user_pod.xml b/packages/SystemUI/res/layout/car_fullscreen_user_pod.xml
index dde2db2..2f16516 100644
--- a/packages/SystemUI/res/layout/car_fullscreen_user_pod.xml
+++ b/packages/SystemUI/res/layout/car_fullscreen_user_pod.xml
@@ -30,7 +30,8 @@
<TextView android:id="@+id/user_name"
android:layout_width="@dimen/car_fullscreen_user_pod_width"
android:layout_height="wrap_content"
- android:layout_marginTop="@dimen/car_fullscreen_user_pod_margin_above_text"
+ android:layout_marginTop="@dimen/car_fullscreen_user_pod_margin_name_top"
+ android:layout_marginBottom="@dimen/car_fullscreen_user_pod_margin_name_bottom"
android:textSize="@dimen/car_fullscreen_user_pod_text_size"
android:textColor="@color/qs_user_detail_name"
android:ellipsize="end"
diff --git a/packages/SystemUI/res/layout/car_qs_footer.xml b/packages/SystemUI/res/layout/car_qs_footer.xml
index 96f34fc..044090b 100644
--- a/packages/SystemUI/res/layout/car_qs_footer.xml
+++ b/packages/SystemUI/res/layout/car_qs_footer.xml
@@ -18,23 +18,24 @@
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/qs_footer"
android:layout_width="match_parent"
- android:layout_height="@dimen/qs_footer_height"
+ android:layout_height="@dimen/car_qs_footer_height"
android:baselineAligned="false"
android:clickable="false"
android:clipChildren="false"
android:clipToPadding="false"
- android:paddingBottom="16dp"
- android:paddingTop="16dp"
- android:paddingEnd="32dp"
- android:paddingStart="32dp"
+ android:paddingBottom="@dimen/car_qs_footer_padding_bottom"
+ android:paddingTop="@dimen/car_qs_footer_padding_top"
+ android:paddingEnd="@dimen/car_qs_footer_padding_end"
+ android:paddingStart="@dimen/car_qs_footer_padding_start"
android:gravity="center_vertical">
<com.android.systemui.statusbar.phone.MultiUserSwitch
android:id="@+id/multi_user_switch"
android:layout_alignParentStart="true"
android:layout_centerVertical="true"
- android:layout_width="48dp"
- android:layout_height="48dp"
+ android:layout_width="@dimen/car_qs_footer_icon_width"
+ android:layout_height="@dimen/car_qs_footer_icon_height"
+ android:layout_marginRight="@dimen/car_qs_footer_user_switch_margin_right"
android:background="@drawable/ripple_drawable"
android:focusable="true">
@@ -43,15 +44,24 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center"
- android:scaleType="centerInside"/>
+ android:scaleType="fitCenter"/>
</com.android.systemui.statusbar.phone.MultiUserSwitch>
+ <TextView android:id="@+id/user_name"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:textSize="@dimen/car_qs_footer_user_name_text_size"
+ android:textColor="@color/car_qs_footer_user_name_color"
+ android:gravity="start|center_vertical"
+ android:layout_centerVertical="true"
+ android:layout_toEndOf="@id/multi_user_switch" />
+
<com.android.systemui.statusbar.phone.SettingsButton
android:id="@+id/settings_button"
android:layout_alignParentEnd="true"
android:layout_centerVertical="true"
- android:layout_width="48dp"
- android:layout_height="48dp"
+ android:layout_width="@dimen/car_qs_footer_icon_width"
+ android:layout_height="@dimen/car_qs_footer_icon_height"
android:background="@drawable/ripple_drawable"
android:contentDescription="@string/accessibility_quick_settings_settings"
android:scaleType="centerCrop"
diff --git a/packages/SystemUI/res/values-h600dp/dimens_car.xml b/packages/SystemUI/res/values-h600dp/dimens_car.xml
new file mode 100644
index 0000000..c3e62c8
--- /dev/null
+++ b/packages/SystemUI/res/values-h600dp/dimens_car.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ * Copyright (c) 2017, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+*/
+-->
+<resources>
+ <dimen name="car_body2_size">32sp</dimen> <!-- B2 -->
+</resources>
diff --git a/packages/SystemUI/res/values/attrs.xml b/packages/SystemUI/res/values/attrs.xml
index 745d6015..a923f0b 100644
--- a/packages/SystemUI/res/values/attrs.xml
+++ b/packages/SystemUI/res/values/attrs.xml
@@ -34,6 +34,7 @@
<attr name="recentItemLayout" format="reference" />
<!-- Style for the "Clear all" button. -->
<attr name="clearAllStyle" format="reference" />
+ <attr name="clearAllBackgroundColor" format="reference" />
</declare-styleable>
<declare-styleable name="DeadZone">
<attr name="minSize" format="dimension" />
diff --git a/packages/SystemUI/res/values/colors.xml b/packages/SystemUI/res/values/colors.xml
index f72f379..f244d88 100644
--- a/packages/SystemUI/res/values/colors.xml
+++ b/packages/SystemUI/res/values/colors.xml
@@ -60,6 +60,11 @@
<!-- The background color for the freeform workspace. -->
<color name="recents_freeform_workspace_bg_color">#33FFFFFF</color>
+ <!-- The background color for clear all button on light backgrounds if not transparent. -->
+ <color name="recents_clear_all_button_bg_light_color">#CCFFFFFF</color>
+ <!-- The background color for clear all button on dark backgrounds if not transparent. -->
+ <color name="recents_clear_all_button_bg_dark_color">#CC000000</color>
+
<color name="keyguard_affordance">#ffffffff</color>
<!-- The color of the legacy notification background -->
diff --git a/packages/SystemUI/res/values/colors_car.xml b/packages/SystemUI/res/values/colors_car.xml
index 1b8c2fa..710b3e0 100644
--- a/packages/SystemUI/res/values/colors_car.xml
+++ b/packages/SystemUI/res/values/colors_car.xml
@@ -20,8 +20,12 @@
<color name="car_qs_background_primary">#263238</color> <!-- Blue Gray 900 -->
<color name="car_user_switcher_progress_bgcolor">#00000000</color> <!-- Transparent -->
<color name="car_user_switcher_progress_fgcolor">#80CBC4</color> <!-- Teal 200 -->
- <color name="car_user_switcher_no_user_image_bgcolor">#FAFAFA</color> <!-- Grey 50 -->
- <color name="car_user_switcher_no_user_image_fgcolor">#212121</color> <!-- Grey 900 -->
- <color name="car_start_driving_background">#FAFAFA</color> <!-- Grey 50 -->
- <color name="car_start_driving_text">#212121</color> <!-- Grey 900 -->
+ <color name="car_user_switcher_no_user_image_bgcolor">@color/car_grey_50</color>
+ <color name="car_user_switcher_no_user_image_fgcolor">@color/car_grey_900</color>
+ <color name="car_start_driving_background">@color/car_grey_50</color>
+ <color name="car_start_driving_text">@color/car_grey_900</color>
+ <color name="car_qs_footer_user_name_color">@color/car_grey_50</color>
+
+ <color name="car_grey_50">#FAFAFA</color>
+ <color name="car_grey_900">#212121</color>
</resources>
diff --git a/packages/SystemUI/res/values/dimens_car.xml b/packages/SystemUI/res/values/dimens_car.xml
index 5f56c4e..8853587 100644
--- a/packages/SystemUI/res/values/dimens_car.xml
+++ b/packages/SystemUI/res/values/dimens_car.xml
@@ -18,7 +18,8 @@
<resources>
<dimen name="car_margin">148dp</dimen>
- <dimen name="car_fullscreen_user_pod_margin_above_text">24dp</dimen>
+ <dimen name="car_fullscreen_user_pod_margin_name_top">24dp</dimen>
+ <dimen name="car_fullscreen_user_pod_margin_name_bottom">64dp</dimen>
<dimen name="car_fullscreen_user_pod_margin_between">24dp</dimen>
<dimen name="car_fullscreen_user_pod_icon_text_size">96dp</dimen>
<dimen name="car_fullscreen_user_pod_image_avatar_width">192dp</dimen>
@@ -37,5 +38,17 @@
<dimen name="car_start_driving_corner_radius">16dp</dimen>
<dimen name="car_start_driving_padding_side">30dp</dimen>
<dimen name="car_start_driving_height">80dp</dimen>
- <dimen name="car_start_driving_text_size">32sp</dimen> <!-- B2 -->
+ <dimen name="car_start_driving_text_size">@dimen/car_body2_size</dimen>
+
+ <dimen name="car_qs_footer_height">112dp</dimen>
+ <dimen name="car_qs_footer_padding_bottom">16dp</dimen>
+ <dimen name="car_qs_footer_padding_top">16dp</dimen>
+ <dimen name="car_qs_footer_padding_end">46dp</dimen>
+ <dimen name="car_qs_footer_padding_start">46dp</dimen>
+ <dimen name="car_qs_footer_icon_width">56dp</dimen>
+ <dimen name="car_qs_footer_icon_height">56dp</dimen>
+ <dimen name="car_qs_footer_user_switch_margin_right">46dp</dimen>
+ <dimen name="car_qs_footer_user_name_text_size">@dimen/car_body2_size</dimen>
+
+ <dimen name="car_body2_size">26sp</dimen>
</resources>
diff --git a/packages/SystemUI/res/values/styles.xml b/packages/SystemUI/res/values/styles.xml
index 2199fff..90c5977 100644
--- a/packages/SystemUI/res/values/styles.xml
+++ b/packages/SystemUI/res/values/styles.xml
@@ -34,11 +34,13 @@
<item name="android:windowShowWallpaper">true</item>
<item name="android:windowDisablePreview">true</item>
<item name="clearAllStyle">@style/ClearAllButtonDefaultMargins</item>
+ <item name="clearAllBackgroundColor">@color/recents_clear_all_button_bg_dark_color</item>
<item name="wallpaperTextColor">@*android:color/primary_text_material_dark</item>
<item name="wallpaperTextColorSecondary">@*android:color/secondary_text_material_dark</item>
</style>
<style name="RecentsTheme.Wallpaper.Light">
+ <item name="clearAllBackgroundColor">@color/recents_clear_all_button_bg_light_color</item>
<item name="wallpaperTextColor">@*android:color/primary_text_material_light</item>
<item name="wallpaperTextColorSecondary">@*android:color/secondary_text_material_light</item>
</style>
diff --git a/packages/SystemUI/src/com/android/systemui/qs/car/CarQSFooter.java b/packages/SystemUI/src/com/android/systemui/qs/car/CarQSFooter.java
index d42b87b..142aab2 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/car/CarQSFooter.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/car/CarQSFooter.java
@@ -22,6 +22,7 @@
import android.view.View;
import android.widget.ImageView;
import android.widget.RelativeLayout;
+import android.widget.TextView;
import com.android.systemui.Dependency;
import com.android.systemui.R;
@@ -44,6 +45,7 @@
private UserInfoController mUserInfoController;
private MultiUserSwitch mMultiUserSwitch;
+ private TextView mUserName;
private ImageView mMultiUserAvatar;
private UserGridView mUserGridView;
@@ -56,6 +58,7 @@
super.onFinishInflate();
mMultiUserSwitch = findViewById(R.id.multi_user_switch);
mMultiUserAvatar = mMultiUserSwitch.findViewById(R.id.multi_user_avatar);
+ mUserName = findViewById(R.id.user_name);
mUserInfoController = Dependency.get(UserInfoController.class);
@@ -89,6 +92,7 @@
@Override
public void onUserInfoChanged(String name, Drawable picture, String userAccount) {
mMultiUserAvatar.setImageDrawable(picture);
+ mUserName.setText(name);
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/qs/external/CustomTile.java b/packages/SystemUI/src/com/android/systemui/qs/external/CustomTile.java
index 017365f..176112b 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/external/CustomTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/external/CustomTile.java
@@ -31,6 +31,7 @@
import android.service.quicksettings.IQSTileService;
import android.service.quicksettings.Tile;
import android.service.quicksettings.TileService;
+import android.text.format.DateUtils;
import android.util.Log;
import android.view.IWindowManager;
import android.view.WindowManagerGlobal;
@@ -51,6 +52,8 @@
public class CustomTile extends QSTileImpl<State> implements TileChangeListener {
public static final String PREFIX = "custom(";
+ private static final long CUSTOM_STALE_TIMEOUT = DateUtils.HOUR_IN_MILLIS;
+
private static final boolean DEBUG = false;
// We don't want to thrash binding and unbinding if the user opens and closes the panel a lot.
@@ -83,6 +86,11 @@
mUser = ActivityManager.getCurrentUser();
}
+ @Override
+ protected long getStaleTimeout() {
+ return CUSTOM_STALE_TIMEOUT + DateUtils.MINUTE_IN_MILLIS * mHost.indexOf(getTileSpec());
+ }
+
private void setTileIcon() {
try {
PackageManager pm = mContext.getPackageManager();
@@ -186,7 +194,7 @@
}
@Override
- public void setListening(boolean listening) {
+ public void handleSetListening(boolean listening) {
if (mListening == listening) return;
mListening = listening;
try {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileImpl.java b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileImpl.java
index 8c04daf..6a5530f 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileImpl.java
@@ -32,10 +32,12 @@
import android.os.Looper;
import android.os.Message;
import android.service.quicksettings.Tile;
+import android.text.format.DateUtils;
import android.util.ArraySet;
import android.util.Log;
import android.util.SparseArray;
+import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.logging.MetricsLogger;
import com.android.settingslib.RestrictedLockUtils;
import com.android.settingslib.Utils;
@@ -45,7 +47,6 @@
import com.android.systemui.plugins.qs.QSIconView;
import com.android.systemui.plugins.qs.QSTile;
import com.android.systemui.plugins.qs.QSTile.State;
-import com.android.systemui.qs.PagedTileLayout;
import com.android.systemui.qs.PagedTileLayout.TilePage;
import com.android.systemui.qs.QSHost;
@@ -62,14 +63,18 @@
protected final String TAG = "Tile." + getClass().getSimpleName();
protected static final boolean DEBUG = Log.isLoggable("Tile", Log.DEBUG);
+ private static final long DEFAULT_STALE_TIMEOUT = 10 * DateUtils.MINUTE_IN_MILLIS;
+
protected final QSHost mHost;
protected final Context mContext;
- protected final H mHandler = new H(Dependency.get(Dependency.BG_LOOPER));
+ // @NonFinalForTesting
+ protected H mHandler = new H(Dependency.get(Dependency.BG_LOOPER));
protected final Handler mUiHandler = new Handler(Looper.getMainLooper());
private final ArraySet<Object> mListeners = new ArraySet<>();
private final MetricsLogger mMetricsLogger = Dependency.get(MetricsLogger.class);
private final ArrayList<Callback> mCallbacks = new ArrayList<>();
+ private final Object mStaleListener = new Object();
protected TState mState = newTileState();
private TState mTmpState = newTileState();
private boolean mAnnounceNextStateChange;
@@ -95,6 +100,7 @@
protected QSTileImpl(QSHost host) {
mHost = host;
mContext = host.getContext();
+ handleStale(); // Tile was just created, must be stale.
}
/**
@@ -106,6 +112,7 @@
if (mListeners.add(listener) && mListeners.size() == 1) {
if (DEBUG) Log.d(TAG, "setListening " + true);
mHandler.obtainMessage(H.SET_LISTENING, 1, 0).sendToTarget();
+ refreshState(); // Ensure we get at least one refresh after listening.
}
} else {
if (mListeners.remove(listener) && mListeners.size() == 0) {
@@ -115,6 +122,15 @@
}
}
+ protected long getStaleTimeout() {
+ return DEFAULT_STALE_TIMEOUT;
+ }
+
+ @VisibleForTesting
+ protected void handleStale() {
+ setListening(mStaleListener, true);
+ }
+
public String getTileSpec() {
return mTileSpec;
}
@@ -273,6 +289,9 @@
if (changed) {
handleStateChanged();
}
+ mHandler.removeMessages(H.STALE);
+ mHandler.sendEmptyMessageDelayed(H.STALE, getStaleTimeout());
+ setListening(mStaleListener, false);
}
private void handleStateChanged() {
@@ -326,11 +345,11 @@
handleRefreshState(null);
}
- protected abstract void setListening(boolean listening);
+ protected abstract void handleSetListening(boolean listening);
protected void handleDestroy() {
if (mListeners.size() != 0) {
- setListening(false);
+ handleSetListening(false);
}
mCallbacks.clear();
}
@@ -380,8 +399,10 @@
private static final int REMOVE_CALLBACKS = 12;
private static final int REMOVE_CALLBACK = 13;
private static final int SET_LISTENING = 14;
+ private static final int STALE = 15;
- private H(Looper looper) {
+ @VisibleForTesting
+ protected H(Looper looper) {
super(looper);
}
@@ -436,8 +457,11 @@
name = "handleClearState";
handleClearState();
} else if (msg.what == SET_LISTENING) {
- name = "setListening";
- setListening(msg.arg1 != 0);
+ name = "handleSetListening";
+ handleSetListening(msg.arg1 != 0);
+ } else if (msg.what == STALE) {
+ name = "handleStale";
+ handleStale();
} else {
throw new IllegalArgumentException("Unknown msg: " + msg.what);
}
@@ -515,7 +539,7 @@
}
}
- protected class AnimationIcon extends ResourceIcon {
+ protected static class AnimationIcon extends ResourceIcon {
private final int mAnimatedResId;
public AnimationIcon(int resId, int staticResId) {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/AirplaneModeTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/AirplaneModeTile.java
index 2e7012e..bef1aff 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/AirplaneModeTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/AirplaneModeTile.java
@@ -110,7 +110,7 @@
}
}
- public void setListening(boolean listening) {
+ public void handleSetListening(boolean listening) {
if (mListening == listening) return;
mListening = listening;
if (listening) {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/BatterySaverTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/BatterySaverTile.java
index 3f419a8..95504ed 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/BatterySaverTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/BatterySaverTile.java
@@ -55,7 +55,7 @@
}
@Override
- public void setListening(boolean listening) {
+ public void handleSetListening(boolean listening) {
if (listening) {
mBatteryController.addCallback(this);
} else {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java
index bc6233d..774f0b3 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java
@@ -76,7 +76,7 @@
}
@Override
- public void setListening(boolean listening) {
+ public void handleSetListening(boolean listening) {
if (listening) {
mController.addCallback(mCallback);
} else {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java
index 2fc9fc7..fb396b9 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java
@@ -91,9 +91,9 @@
}
@Override
- public void setListening(boolean listening) {
+ public void handleSetListening(boolean listening) {
if (mController == null) return;
- if (DEBUG) Log.d(TAG, "setListening " + listening);
+ if (DEBUG) Log.d(TAG, "handleSetListening " + listening);
if (listening) {
mController.addCallback(mCallback);
mKeyguard.addCallback(mCallback);
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java
index f900da0..0bb7479 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java
@@ -92,7 +92,7 @@
}
@Override
- public void setListening(boolean listening) {
+ public void handleSetListening(boolean listening) {
if (listening) {
mController.addCallback(mSignalCallback);
} else {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/ColorInversionTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/ColorInversionTile.java
index 40fe484..b93f1c2 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/ColorInversionTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/ColorInversionTile.java
@@ -63,7 +63,7 @@
}
@Override
- public void setListening(boolean listening) {
+ public void handleSetListening(boolean listening) {
mSetting.setListening(listening);
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/DataSaverTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/DataSaverTile.java
index 8b62beb..a102696 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/DataSaverTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/DataSaverTile.java
@@ -45,7 +45,7 @@
}
@Override
- public void setListening(boolean listening) {
+ public void handleSetListening(boolean listening) {
if (listening) {
mDataSaverController.addCallback(this);
} else {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java
index 5938749..9e265e22 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java
@@ -232,7 +232,7 @@
}
@Override
- public void setListening(boolean listening) {
+ public void handleSetListening(boolean listening) {
if (mListening == listening) return;
mListening = listening;
if (mListening) {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/FlashlightTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/FlashlightTile.java
index e6ac908..f2ead1c 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/FlashlightTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/FlashlightTile.java
@@ -54,7 +54,7 @@
}
@Override
- public void setListening(boolean listening) {
+ public void handleSetListening(boolean listening) {
if (listening) {
mFlashlightController.addCallback(this);
} else {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/HotspotTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/HotspotTile.java
index c17573d..910b6b1 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/HotspotTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/HotspotTile.java
@@ -74,7 +74,7 @@
}
@Override
- public void setListening(boolean listening) {
+ public void handleSetListening(boolean listening) {
if (mListening == listening) return;
mListening = listening;
if (listening) {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/IntentTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/IntentTile.java
index 00cfbfa..4f4004c 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/IntentTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/IntentTile.java
@@ -76,7 +76,7 @@
}
@Override
- public void setListening(boolean listening) {
+ public void handleSetListening(boolean listening) {
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/LocationTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/LocationTile.java
index 5e66334..c35f591 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/LocationTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/LocationTile.java
@@ -55,7 +55,7 @@
}
@Override
- public void setListening(boolean listening) {
+ public void handleSetListening(boolean listening) {
if (listening) {
mController.addCallback(mCallback);
mKeyguard.addCallback(mCallback);
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/NfcTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/NfcTile.java
index 6500740..b3ff4e5b 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/NfcTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/NfcTile.java
@@ -51,7 +51,7 @@
}
@Override
- public void setListening(boolean listening) {
+ public void handleSetListening(boolean listening) {
mListening = listening;
if (mListening) {
mContext.registerReceiver(mNfcReceiver,
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/NightDisplayTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/NightDisplayTile.java
index 2a12769..4c20361 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/NightDisplayTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/NightDisplayTile.java
@@ -95,7 +95,7 @@
}
@Override
- protected void setListening(boolean listening) {
+ protected void handleSetListening(boolean listening) {
mIsListening = listening;
if (listening) {
mController.setListener(this);
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/RotationLockTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/RotationLockTile.java
index fb937bd..1e00894 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/RotationLockTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/RotationLockTile.java
@@ -62,7 +62,7 @@
return new BooleanState();
}
- public void setListening(boolean listening) {
+ public void handleSetListening(boolean listening) {
if (mController == null) return;
if (listening) {
mController.addCallback(mCallback);
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/UserTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/UserTile.java
index d6043f4..bde1c98 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/UserTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/UserTile.java
@@ -69,7 +69,7 @@
}
@Override
- public void setListening(boolean listening) {
+ public void handleSetListening(boolean listening) {
if (listening) {
mUserInfoController.addCallback(this);
} else {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java
index 136cf21..33b1512 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java
@@ -75,7 +75,7 @@
}
@Override
- public void setListening(boolean listening) {
+ public void handleSetListening(boolean listening) {
if (listening) {
mController.addCallback(mSignalCallback);
} else {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/WorkModeTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/WorkModeTile.java
index 38821f6..5f7d6fb 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/WorkModeTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/WorkModeTile.java
@@ -48,7 +48,7 @@
}
@Override
- public void setListening(boolean listening) {
+ public void handleSetListening(boolean listening) {
if (listening) {
mProfileController.addCallback(this);
} else {
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
index f844866..f545556 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
@@ -65,6 +65,7 @@
import com.android.systemui.recents.events.activity.LaunchTaskFailedEvent;
import com.android.systemui.recents.events.activity.LaunchTaskSucceededEvent;
import com.android.systemui.recents.events.activity.MultiWindowStateChangedEvent;
+import com.android.systemui.recents.events.activity.RecentsActivityStartingEvent;
import com.android.systemui.recents.events.activity.ToggleRecentsEvent;
import com.android.systemui.recents.events.component.ActivityUnpinnedEvent;
import com.android.systemui.recents.events.component.RecentsVisibilityChangedEvent;
@@ -119,6 +120,7 @@
private boolean mFinishedOnStartup;
private boolean mIgnoreAltTabRelease;
private boolean mIsVisible;
+ private boolean mRecentsStartRequested;
private Configuration mLastConfig;
// Top level views
@@ -416,6 +418,7 @@
launchState.launchedFromHome = false;
onEnterAnimationComplete();
}
+ mRecentsStartRequested = false;
}
@Override
@@ -449,7 +452,6 @@
* Reloads the stack views upon launching Recents.
*/
private void reloadStackView() {
-
// If the Recents component has preloaded a load plan, then use that to prevent
// reconstructing the task stack
RecentsTaskLoader loader = Recents.getTaskLoader();
@@ -572,7 +574,9 @@
MetricsLogger.hidden(this, MetricsEvent.OVERVIEW_ACTIVITY);
Recents.getTaskLoader().getHighResThumbnailLoader().setVisible(false);
- if (!isChangingConfigurations()) {
+ // When recents starts again before onStop, do not reset launch flags so entrance animation
+ // can run
+ if (!isChangingConfigurations() && !mRecentsStartRequested) {
// Workaround for b/22542869, if the RecentsActivity is started again, but without going
// through SystemUI, we need to reset the config launch flags to ensure that we do not
// wait on the system to send a signal that was never queued.
@@ -718,6 +722,10 @@
MetricsLogger.action(this, MetricsEvent.ACTION_OVERVIEW_PAGE);
}
+ public final void onBusEvent(RecentsActivityStartingEvent event) {
+ mRecentsStartRequested = true;
+ }
+
public final void onBusEvent(UserInteractionEvent event) {
// Stop the fast-toggle dozer
mIterateTrigger.stopDozing();
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java
index 71f06cb..c44cd72 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java
@@ -205,6 +205,10 @@
mStackButtonShadowDistance.x, mStackButtonShadowDistance.y,
mStackButtonShadowColor);
}
+ if (Recents.getConfiguration().isLowRamDevice) {
+ int bgColor = Utils.getColorAttr(mContext, R.attr.clearAllBackgroundColor);
+ mStackActionButton.setBackgroundColor(bgColor);
+ }
}
// Let's also require dark status and nav bars if the text is dark
@@ -955,8 +959,8 @@
int left, top;
if (Recents.getConfiguration().isLowRamDevice) {
Rect windowRect = Recents.getSystemServices().getWindowRect();
- left = (windowRect.width() - mSystemInsets.left - mSystemInsets.right
- - mStackActionButton.getMeasuredWidth()) / 2;
+ int spaceLeft = windowRect.width() - mSystemInsets.left - mSystemInsets.right;
+ left = (spaceLeft - mStackActionButton.getMeasuredWidth()) / 2 + mSystemInsets.left;
top = windowRect.height() - (mStackActionButton.getMeasuredHeight()
+ mSystemInsets.bottom + mStackActionButton.getPaddingBottom() / 2);
} else {
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java
index a633a3e..8899e30 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java
@@ -2396,10 +2396,14 @@
}
private void updateStackActionButtonVisibility() {
+ if (Recents.getConfiguration().isLowRamDevice) {
+ return;
+ }
+
// Always show the button in grid layout.
if (useGridLayout() ||
(mStackScroller.getStackScroll() < SHOW_STACK_ACTION_BUTTON_SCROLL_THRESHOLD &&
- mStack.getTaskCount() > 0 && !Recents.getConfiguration().isLowRamDevice)) {
+ mStack.getTaskCount() > 0)) {
EventBus.getDefault().send(new ShowStackActionButtonEvent(false /* translate */));
} else {
EventBus.getDefault().send(new HideStackActionButtonEvent());
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/lowram/TaskStackLowRamLayoutAlgorithm.java b/packages/SystemUI/src/com/android/systemui/recents/views/lowram/TaskStackLowRamLayoutAlgorithm.java
index 52fa7b5..17e6b9e 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/lowram/TaskStackLowRamLayoutAlgorithm.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/lowram/TaskStackLowRamLayoutAlgorithm.java
@@ -126,7 +126,6 @@
return transformOut;
}
boolean visible = true;
- int x = mPaddingLeftRight;
int y;
if (taskCount > 1) {
y = getTaskTopFromIndex(taskIndex) - percentageToScroll(stackScroll);
@@ -255,7 +254,7 @@
transformOut.dimAlpha = 0f;
transformOut.viewOutlineAlpha = 1f;
transformOut.rect.set(getTaskRect());
- transformOut.rect.offset(mPaddingLeftRight, y);
+ transformOut.rect.offset(mPaddingLeftRight + mSystemInsets.left, y);
Utilities.scaleRectAboutCenter(transformOut.rect, transformOut.scale);
transformOut.visible = visible;
}
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java b/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java
index a35310f..991c3c8 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java
@@ -16,11 +16,16 @@
package com.android.systemui.screenshot;
+import static com.android.systemui.screenshot.GlobalScreenshot.SHARING_INTENT;
+import static com.android.systemui.statusbar.phone.StatusBar.SYSTEM_DIALOG_REASON_SCREENSHOT;
+
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
import android.animation.ValueAnimator;
import android.animation.ValueAnimator.AnimatorUpdateListener;
+import android.app.ActivityManager;
+import android.app.ActivityOptions;
import android.app.admin.DevicePolicyManager;
import android.app.Notification;
import android.app.Notification.BigPictureStyle;
@@ -48,6 +53,7 @@
import android.os.Environment;
import android.os.PowerManager;
import android.os.Process;
+import android.os.RemoteException;
import android.os.UserHandle;
import android.provider.MediaStore;
import android.util.DisplayMetrics;
@@ -277,14 +283,13 @@
sharingIntent.putExtra(Intent.EXTRA_STREAM, uri);
sharingIntent.putExtra(Intent.EXTRA_SUBJECT, subject);
- // Create a share action for the notification
- PendingIntent chooseAction = PendingIntent.getBroadcast(context, 0,
- new Intent(context, GlobalScreenshot.TargetChosenReceiver.class),
- PendingIntent.FLAG_CANCEL_CURRENT | PendingIntent.FLAG_ONE_SHOT);
- Intent chooserIntent = Intent.createChooser(sharingIntent, null,
- chooseAction.getIntentSender())
- .addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK);
- PendingIntent shareAction = PendingIntent.getActivity(context, 0, chooserIntent,
+ // Create a share action for the notification. Note, we proxy the call to ShareReceiver
+ // because RemoteViews currently forces an activity options on the PendingIntent being
+ // launched, and since we don't want to trigger the share sheet in this case, we will
+ // start the chooser activitiy directly in ShareReceiver.
+ PendingIntent shareAction = PendingIntent.getBroadcast(context, 0,
+ new Intent(context, GlobalScreenshot.ShareReceiver.class)
+ .putExtra(SHARING_INTENT, sharingIntent),
PendingIntent.FLAG_CANCEL_CURRENT);
Notification.Action.Builder shareActionBuilder = new Notification.Action.Builder(
R.drawable.ic_screenshot_share,
@@ -292,7 +297,7 @@
mNotificationBuilder.addAction(shareActionBuilder.build());
// Create a delete action for the notification
- PendingIntent deleteAction = PendingIntent.getBroadcast(context, 0,
+ PendingIntent deleteAction = PendingIntent.getBroadcast(context, 0,
new Intent(context, GlobalScreenshot.DeleteScreenshotReceiver.class)
.putExtra(GlobalScreenshot.SCREENSHOT_URI_ID, uri.toString()),
PendingIntent.FLAG_CANCEL_CURRENT | PendingIntent.FLAG_ONE_SHOT);
@@ -403,6 +408,7 @@
class GlobalScreenshot {
static final String SCREENSHOT_URI_ID = "android:screenshot_uri_id";
+ static final String SHARING_INTENT = "android:screenshot_sharing_intent";
private static final int SCREENSHOT_FLASH_TO_PEAK_DURATION = 130;
private static final int SCREENSHOT_DROP_IN_DURATION = 430;
@@ -897,6 +903,30 @@
}
/**
+ * Receiver to proxy the share intent.
+ */
+ public static class ShareReceiver extends BroadcastReceiver {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ try {
+ ActivityManager.getService().closeSystemDialogs(SYSTEM_DIALOG_REASON_SCREENSHOT);
+ } catch (RemoteException e) {
+ }
+
+ Intent sharingIntent = intent.getParcelableExtra(SHARING_INTENT);
+ PendingIntent chooseAction = PendingIntent.getBroadcast(context, 0,
+ new Intent(context, GlobalScreenshot.TargetChosenReceiver.class),
+ PendingIntent.FLAG_CANCEL_CURRENT | PendingIntent.FLAG_ONE_SHOT);
+ Intent chooserIntent = Intent.createChooser(sharingIntent, null,
+ chooseAction.getIntentSender())
+ .addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK);
+ ActivityOptions opts = ActivityOptions.makeBasic();
+ opts.setDisallowEnterPictureInPictureWhileLaunching(true);
+ context.startActivityAsUser(chooserIntent, opts.toBundle(), UserHandle.CURRENT);
+ }
+ }
+
+ /**
* Removes the notification for a screenshot after a share target is chosen.
*/
public static class TargetChosenReceiver extends BroadcastReceiver {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationInfo.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationInfo.java
index 1ffb3b5..3b23a0c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationInfo.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationInfo.java
@@ -126,7 +126,7 @@
| PackageManager.MATCH_DIRECT_BOOT_UNAWARE
| PackageManager.MATCH_DIRECT_BOOT_AWARE);
if (info != null) {
- mAppUid = info.uid;
+ mAppUid = sbn.getUid();
mAppName = String.valueOf(pm.getApplicationLabel(info));
pkgicon = pm.getApplicationIcon(info);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationHeaderViewWrapper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationHeaderViewWrapper.java
index fcc982ea..b95b8a3 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationHeaderViewWrapper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationHeaderViewWrapper.java
@@ -114,7 +114,6 @@
mIcon = mView.findViewById(com.android.internal.R.id.icon);
mHeaderText = mView.findViewById(com.android.internal.R.id.header_text);
mExpandButton = mView.findViewById(com.android.internal.R.id.expand_button);
- mExpandButton.setLabeledBy(mRow);
mWorkProfileImage = mView.findViewById(com.android.internal.R.id.profile_badge);
mColor = resolveColor(mExpandButton);
mNotificationHeader = mView.findViewById(com.android.internal.R.id.notification_header);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/BarTransitions.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/BarTransitions.java
index f379a46..1f44abe 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/BarTransitions.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/BarTransitions.java
@@ -41,8 +41,6 @@
private static final boolean DEBUG = false;
private static final boolean DEBUG_COLORS = false;
- public static final boolean HIGH_END = ActivityManager.isHighEndGfx();
-
public static final int MODE_OPAQUE = 0;
public static final int MODE_SEMI_TRANSPARENT = 1;
public static final int MODE_TRANSLUCENT = 2;
@@ -66,9 +64,7 @@
mTag = "BarTransitions." + view.getClass().getSimpleName();
mView = view;
mBarBackground = new BarBackgroundDrawable(mView.getContext(), gradientResourceId);
- if (HIGH_END) {
- mView.setBackground(mBarBackground);
- }
+ mView.setBackground(mBarBackground);
}
public int getMode() {
@@ -89,7 +85,7 @@
public boolean isAlwaysOpaque() {
// Low-end devices do not support translucent modes, fallback to opaque
- return !HIGH_END || mAlwaysOpaque;
+ return mAlwaysOpaque;
}
public void transitionTo(int mode, boolean animate) {
@@ -109,9 +105,7 @@
}
protected void onTransition(int oldMode, int newMode, boolean animate) {
- if (HIGH_END) {
- applyModeBackground(oldMode, newMode, animate);
- }
+ applyModeBackground(oldMode, newMode, animate);
}
protected void applyModeBackground(int oldMode, int newMode, boolean animate) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CollapsedStatusBarFragment.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CollapsedStatusBarFragment.java
index 8c923cb..2c3f452 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CollapsedStatusBarFragment.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CollapsedStatusBarFragment.java
@@ -161,10 +161,6 @@
showNotificationIconArea(animate);
}
}
- if (!BarTransitions.HIGH_END) {
- int mask = DISABLE_NOTIFICATION_ICONS | DISABLE_SYSTEM_INFO;
- getView().setVisibility((mDisabled1 & mask) == mask ? View.GONE : View.VISIBLE);
- }
}
protected int adjustDisableFlags(int state) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LightBarTransitionsController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LightBarTransitionsController.java
index d3a6280..b0ac6ec 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LightBarTransitionsController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LightBarTransitionsController.java
@@ -127,11 +127,6 @@
}
public void setIconsDark(boolean dark, boolean animate) {
- if (!BarTransitions.HIGH_END) {
- setIconTintInternal(0.0f);
- mNextDarkIntensity = 0.0f;
- return;
- }
if (!animate) {
setIconTintInternal(dark ? 1.0f : 0.0f);
mNextDarkIntensity = dark ? 1.0f : 0.0f;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
index 7aebfdc5..7c6e886 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
@@ -300,6 +300,7 @@
// Should match the values in PhoneWindowManager
public static final String SYSTEM_DIALOG_REASON_HOME_KEY = "homekey";
public static final String SYSTEM_DIALOG_REASON_RECENT_APPS = "recentapps";
+ static public final String SYSTEM_DIALOG_REASON_SCREENSHOT = "screenshot";
private static final String BANNER_ACTION_CANCEL =
"com.android.systemui.statusbar.banner_action_cancel";
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tileimpl/QSTileImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/tileimpl/QSTileImplTest.java
index 0500a54..004ff29 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/tileimpl/QSTileImplTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tileimpl/QSTileImplTest.java
@@ -21,13 +21,19 @@
import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_QS_VALUE;
import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.TYPE_ACTION;
+import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Matchers.argThat;
+import static org.mockito.Mockito.clearInvocations;
import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
+import static java.lang.Thread.sleep;
+
import android.content.Intent;
import android.metrics.LogMaker;
import android.support.test.filters.SmallTest;
@@ -66,10 +72,10 @@
mMetricsLogger = mDependency.injectMockDependency(MetricsLogger.class);
mHost = mock(QSTileHost.class);
when(mHost.indexOf(spec)).thenReturn(POSITION);
- mTestableLooper.runWithLooper(() -> {
- mTile = new TileImpl(mHost);
- mTile.setTileSpec(spec);
- });
+
+ mTile = spy(new TileImpl(mHost));
+ mTile.mHandler = mTile.new H(mTestableLooper.getLooper());
+ mTile.setTileSpec(spec);
}
@Test
@@ -94,12 +100,38 @@
public void testPopulate() {
LogMaker maker = mock(LogMaker.class);
when(maker.setSubtype(anyInt())).thenReturn(maker);
+ when(maker.addTaggedData(anyInt(), any())).thenReturn(maker);
mTile.getState().value = true;
mTile.populate(maker);
verify(maker).addTaggedData(eq(FIELD_QS_VALUE), eq(1));
verify(maker).addTaggedData(eq(FIELD_QS_POSITION), eq(POSITION));
}
+ @Test
+ public void testStaleTimeout() throws InterruptedException {
+ when(mTile.getStaleTimeout()).thenReturn(5l);
+ clearInvocations(mTile);
+
+ mTile.handleRefreshState(null);
+ mTestableLooper.processAllMessages();
+ verify(mTile, never()).handleStale();
+
+ sleep(10);
+ mTestableLooper.processAllMessages();
+ verify(mTile).handleStale();
+ }
+
+ @Test
+ public void testStaleListening() {
+ mTile.handleStale();
+ mTestableLooper.processAllMessages();
+ verify(mTile).handleSetListening(eq(true));
+
+ mTile.handleRefreshState(null);
+ mTestableLooper.processAllMessages();
+ verify(mTile).handleSetListening(eq(false));
+ }
+
private class TileLogMatcher implements ArgumentMatcher<LogMaker> {
private final int mCategory;
@@ -164,7 +196,7 @@
}
@Override
- protected void setListening(boolean listening) {
+ protected void handleSetListening(boolean listening) {
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationInfoTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationInfoTest.java
index b6827ea..88fa659 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationInfoTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationInfoTest.java
@@ -121,7 +121,7 @@
mDefaultNotificationChannel = new NotificationChannel(
NotificationChannel.DEFAULT_CHANNEL_ID, TEST_CHANNEL_NAME,
NotificationManager.IMPORTANCE_LOW);
- mSbn = new StatusBarNotification(TEST_PACKAGE_NAME, TEST_PACKAGE_NAME, 0, null, 0, 0,
+ mSbn = new StatusBarNotification(TEST_PACKAGE_NAME, TEST_PACKAGE_NAME, 0, null, TEST_UID, 0,
new Notification(), UserHandle.CURRENT, null, 0);
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/ExtensionControllerImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/ExtensionControllerImplTest.java
index a915cb20..b22a646 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/ExtensionControllerImplTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/ExtensionControllerImplTest.java
@@ -27,7 +27,6 @@
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
import android.testing.TestableLooper.RunWithLooper;
-import android.util.Log;
import com.android.systemui.Dependency;
import com.android.systemui.SysuiTestCase;
@@ -145,7 +144,6 @@
@Test
@RunWithLooper
public void testSortOrder() {
- Log.d("TestTest", "Config " + mContext.getResources().getConfiguration().uiMode);
Object def = new Object();
Object uiMode = new Object();
Object tuner = new Object();
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/IconLoggerImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/IconLoggerImplTest.java
index 66a8561..ec994a1 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/IconLoggerImplTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/IconLoggerImplTest.java
@@ -32,6 +32,7 @@
import static java.lang.Thread.sleep;
import android.metrics.LogMaker;
+import android.support.test.filters.SmallTest;
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
import android.testing.TestableLooper.MessageHandler;
@@ -48,6 +49,7 @@
@RunWith(AndroidTestingRunner.class)
@RunWithLooper
+@SmallTest
public class IconLoggerImplTest extends SysuiTestCase {
private MetricsLogger mMetricsLogger;
@@ -172,4 +174,4 @@
return true;
}));
}
-}
\ No newline at end of file
+}
diff --git a/proto/src/metrics_constants.proto b/proto/src/metrics_constants.proto
index 9fbec70..eb895de 100644
--- a/proto/src/metrics_constants.proto
+++ b/proto/src/metrics_constants.proto
@@ -4300,6 +4300,11 @@
// OS: O MR
FIELD_NUM_STATUS_ICONS = 1095;
+ // ACTION: Logged when user tries to pair a Bluetooth device without name from Settings app
+ // CATEGORY: SETTINGS
+ // OS: O MR
+ ACTION_SETTINGS_BLUETOOTH_PAIR_DEVICES_WITHOUT_NAMES = 1096;
+
// Add new aosp constants above this line.
// END OF AOSP CONSTANTS
}
diff --git a/services/autofill/java/com/android/server/autofill/Session.java b/services/autofill/java/com/android/server/autofill/Session.java
index 95db603..d81cd64 100644
--- a/services/autofill/java/com/android/server/autofill/Session.java
+++ b/services/autofill/java/com/android/server/autofill/Session.java
@@ -456,14 +456,7 @@
}
}
if (response == null) {
- if (sVerbose) Slog.v(TAG, "canceling session " + id + " when server returned null");
- if ((requestFlags & FLAG_MANUAL_REQUEST) != 0) {
- getUiForShowing().showError(R.string.autofill_error_cannot_autofill, this);
- }
- mService.resetLastResponse();
- // Nothing to be done, but need to notify client.
- notifyUnavailableToClient();
- removeSelf();
+ processNullResponseLocked(requestFlags);
return;
}
@@ -748,16 +741,24 @@
}
final Parcelable result = data.getParcelable(AutofillManager.EXTRA_AUTHENTICATION_RESULT);
+ if (sDebug) Slog.d(TAG, "setAuthenticationResultLocked(): result=" + result);
if (result instanceof FillResponse) {
final FillResponse response = (FillResponse) result;
mMetricsLogger.action(MetricsEvent.AUTOFILL_AUTHENTICATED, mPackageName);
replaceResponseLocked(authenticatedResponse, response);
} else if (result instanceof Dataset) {
+ // TODO: add proper metric
if (datasetIdx != AutofillManager.AUTHENTICATION_ID_DATASET_ID_UNDEFINED) {
final Dataset dataset = (Dataset) result;
authenticatedResponse.getDatasets().set(datasetIdx, dataset);
autoFill(requestId, datasetIdx, dataset);
}
+ } else {
+ if (result != null) {
+ Slog.w(TAG, "service returned invalid auth type: " + result);
+ }
+ // TODO: add proper metric (on else)
+ processNullResponseLocked(0);
}
}
@@ -1409,6 +1410,17 @@
processResponseLocked(newResponse, 0);
}
+ private void processNullResponseLocked(int flags) {
+ if (sVerbose) Slog.v(TAG, "canceling session " + id + " when server returned null");
+ if ((flags & FLAG_MANUAL_REQUEST) != 0) {
+ getUiForShowing().showError(R.string.autofill_error_cannot_autofill, this);
+ }
+ mService.resetLastResponse();
+ // Nothing to be done, but need to notify client.
+ notifyUnavailableToClient();
+ removeSelf();
+ }
+
private void processResponseLocked(@NonNull FillResponse newResponse, int flags) {
// Make sure we are hiding the UI which will be shown
// only if handling the current response requires it.
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index 04b2112..f1ea853 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -4343,11 +4343,13 @@
int currentScore, NetworkMisc networkMisc) {
enforceConnectivityInternalPermission();
+ LinkProperties lp = new LinkProperties(linkProperties);
+ lp.ensureDirectlyConnectedRoutes();
// TODO: Instead of passing mDefaultRequest, provide an API to determine whether a Network
// satisfies mDefaultRequest.
final NetworkAgentInfo nai = new NetworkAgentInfo(messenger, new AsyncChannel(),
- new Network(reserveNetId()), new NetworkInfo(networkInfo), new LinkProperties(
- linkProperties), new NetworkCapabilities(networkCapabilities), currentScore,
+ new Network(reserveNetId()), new NetworkInfo(networkInfo), lp,
+ new NetworkCapabilities(networkCapabilities), currentScore,
mContext, mTrackerHandler, new NetworkMisc(networkMisc), mDefaultRequest, this);
synchronized (this) {
nai.networkMonitor.systemReady = mSystemReady;
@@ -4657,6 +4659,8 @@
synchronized (nai) {
nai.linkProperties = newLp;
}
+ // msg.obj is already a defensive copy.
+ nai.linkProperties.ensureDirectlyConnectedRoutes();
if (nai.everConnected) {
updateLinkProperties(nai, oldLp);
}
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index dad3125..85fa7a1 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -13231,7 +13231,6 @@
return;
}
}
-
// We are now ready to launch the assist activity.
IResultReceiver sendReceiver = null;
Bundle sendBundle = null;
@@ -13261,17 +13260,24 @@
return;
}
- long ident = Binder.clearCallingIdentity();
+ final long ident = Binder.clearCallingIdentity();
try {
- pae.intent.replaceExtras(pae.extras);
- pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
- | Intent.FLAG_ACTIVITY_SINGLE_TOP
- | Intent.FLAG_ACTIVITY_CLEAR_TOP);
- closeSystemDialogs("assist");
- try {
- mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
- } catch (ActivityNotFoundException e) {
- Slog.w(TAG, "No activity to handle assist action.", e);
+ if (TextUtils.equals(pae.intent.getAction(),
+ android.service.voice.VoiceInteractionService.SERVICE_INTERFACE)) {
+ pae.intent.putExtras(pae.extras);
+ mContext.startServiceAsUser(pae.intent, new UserHandle(pae.userHandle));
+ } else {
+ pae.intent.replaceExtras(pae.extras);
+ pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
+ | Intent.FLAG_ACTIVITY_SINGLE_TOP
+ | Intent.FLAG_ACTIVITY_CLEAR_TOP);
+ closeSystemDialogs("assist");
+
+ try {
+ mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
+ } catch (ActivityNotFoundException e) {
+ Slog.w(TAG, "No activity to handle assist action.", e);
+ }
}
} finally {
Binder.restoreCallingIdentity(ident);
diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java
index 35ba591..56ae57b 100644
--- a/services/core/java/com/android/server/am/ActivityStack.java
+++ b/services/core/java/com/android/server/am/ActivityStack.java
@@ -3012,13 +3012,6 @@
// Ensure the task/activity being brought forward is not the assistant
return false;
}
- final boolean isFullscreen = toFrontTask != null
- ? toFrontTask.containsOnlyFullscreenActivities()
- : toFrontActivity.fullscreen;
- if (!isFullscreen) {
- // Ensure the task/activity being brought forward is fullscreen
- return false;
- }
return true;
}
diff --git a/services/core/java/com/android/server/am/TaskRecord.java b/services/core/java/com/android/server/am/TaskRecord.java
index 1bbb068..eadc8a6 100644
--- a/services/core/java/com/android/server/am/TaskRecord.java
+++ b/services/core/java/com/android/server/am/TaskRecord.java
@@ -1112,19 +1112,6 @@
return intent != null ? intent : affinityIntent;
}
- /**
- * @return Whether there are only fullscreen activities in this task.
- */
- boolean containsOnlyFullscreenActivities() {
- for (int i = 0; i < mActivities.size(); i++) {
- final ActivityRecord r = mActivities.get(i);
- if (!r.finishing && !r.fullscreen) {
- return false;
- }
- }
- return true;
- }
-
/** Returns the first non-finishing activity from the root. */
ActivityRecord getRootActivity() {
for (int i = 0; i < mActivities.size(); i++) {
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index 44e571a..e578485 100644
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -1461,8 +1461,18 @@
if (channel.getImportance() == NotificationManager.IMPORTANCE_NONE) {
// cancel
cancelAllNotificationsInt(MY_UID, MY_PID, pkg, channel.getId(), 0, 0, true,
- UserHandle.getUserId(Binder.getCallingUid()), REASON_CHANNEL_BANNED,
+ UserHandle.getUserId(uid), REASON_CHANNEL_BANNED,
null);
+ if (isUidSystemOrPhone(uid)) {
+ int[] profileIds = mUserProfiles.getCurrentProfileIds();
+ int N = profileIds.length;
+ for (int i = 0; i < N; i++) {
+ int profileId = profileIds[i];
+ cancelAllNotificationsInt(MY_UID, MY_PID, pkg, channel.getId(), 0, 0, true,
+ profileId, REASON_CHANNEL_BANNED,
+ null);
+ }
+ }
}
mRankingHelper.updateNotificationChannel(pkg, uid, channel);
diff --git a/services/core/java/com/android/server/oemlock/OemLockService.java b/services/core/java/com/android/server/oemlock/OemLockService.java
index 5e19b13..40c6639 100644
--- a/services/core/java/com/android/server/oemlock/OemLockService.java
+++ b/services/core/java/com/android/server/oemlock/OemLockService.java
@@ -149,8 +149,12 @@
final long token = Binder.clearCallingIdentity();
try {
- if (!canUserAllowOemUnlock()) {
- throw new SecurityException("User cannot allow OEM unlock");
+ if (!isOemUnlockAllowedByAdmin()) {
+ throw new SecurityException("Admin does not allow OEM unlock");
+ }
+
+ if (!mOemLock.isOemUnlockAllowedByCarrier()) {
+ throw new SecurityException("Carrier does not allow OEM unlock");
}
mOemLock.setOemUnlockAllowedByDevice(allowedByUser);
@@ -172,18 +176,6 @@
}
@Override
- public boolean canUserAllowOemUnlock() {
- enforceOemUnlockReadPermission();
-
- final long token = Binder.clearCallingIdentity();
- try {
- return isOemUnlockAllowedByAdmin() && mOemLock.isOemUnlockAllowedByCarrier();
- } finally {
- Binder.restoreCallingIdentity(token);
- }
- }
-
- @Override
public boolean isOemUnlockAllowed() {
enforceOemUnlockReadPermission();
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 20fb350..4145e60 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -8512,7 +8512,7 @@
continue;
}
if (filterAppAccessLPr(ps, callingUid, userId)) {
- return null;
+ continue;
}
final PackageInfo pi = generatePackageInfo(ps, flags, userId);
if (pi != null) {
@@ -8527,7 +8527,7 @@
continue;
}
if (filterAppAccessLPr(ps, callingUid, userId)) {
- return null;
+ continue;
}
final PackageInfo pi = generatePackageInfo((PackageSetting)
p.mExtras, flags, userId);
@@ -8639,7 +8639,7 @@
continue;
}
if (filterAppAccessLPr(ps, callingUid, userId)) {
- return null;
+ continue;
}
ai = PackageParser.generateApplicationInfo(ps.pkg, effectiveFlags,
ps.readUserState(userId), userId);
@@ -8665,7 +8665,7 @@
continue;
}
if (filterAppAccessLPr(ps, callingUid, userId)) {
- return null;
+ continue;
}
ApplicationInfo ai = PackageParser.generateApplicationInfo(p, flags,
ps.readUserState(userId), userId);
diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java
index e6c6622..48d6cdc 100644
--- a/services/core/java/com/android/server/pm/UserManagerService.java
+++ b/services/core/java/com/android/server/pm/UserManagerService.java
@@ -128,6 +128,7 @@
*
* Method naming convention:
* <ul>
+ * <li> Methods suffixed with "LAr" should be called within the {@link #mAppRestrictionsLock} lock.
* <li> Methods suffixed with "LP" should be called within the {@link #mPackagesLock} lock.
* <li> Methods suffixed with "LR" should be called within the {@link #mRestrictionsLock} lock.
* <li> Methods suffixed with "LU" should be called within the {@link #mUsersLock} lock.
@@ -232,6 +233,8 @@
// Short-term lock for internal state, when interaction/sync with PM is not required
private final Object mUsersLock = LockGuard.installNewLock(LockGuard.INDEX_USER);
private final Object mRestrictionsLock = new Object();
+ // Used for serializing access to app restriction files
+ private final Object mAppRestrictionsLock = new Object();
private final Handler mHandler;
@@ -2328,13 +2331,11 @@
/**
* Removes the app restrictions file for a specific package and user id, if it exists.
*/
- private void cleanAppRestrictionsForPackage(String pkg, int userId) {
- synchronized (mPackagesLock) {
- File dir = Environment.getUserSystemDirectory(userId);
- File resFile = new File(dir, packageToRestrictionsFileName(pkg));
- if (resFile.exists()) {
- resFile.delete();
- }
+ private static void cleanAppRestrictionsForPackageLAr(String pkg, int userId) {
+ File dir = Environment.getUserSystemDirectory(userId);
+ File resFile = new File(dir, packageToRestrictionsFileName(pkg));
+ if (resFile.exists()) {
+ resFile.delete();
}
}
@@ -2853,9 +2854,9 @@
|| !UserHandle.isSameApp(Binder.getCallingUid(), getUidForPackage(packageName))) {
checkSystemOrRoot("get application restrictions for other user/app " + packageName);
}
- synchronized (mPackagesLock) {
+ synchronized (mAppRestrictionsLock) {
// Read the restrictions from XML
- return readApplicationRestrictionsLP(packageName, userId);
+ return readApplicationRestrictionsLAr(packageName, userId);
}
}
@@ -2866,12 +2867,12 @@
if (restrictions != null) {
restrictions.setDefusable(true);
}
- synchronized (mPackagesLock) {
+ synchronized (mAppRestrictionsLock) {
if (restrictions == null || restrictions.isEmpty()) {
- cleanAppRestrictionsForPackage(packageName, userId);
+ cleanAppRestrictionsForPackageLAr(packageName, userId);
} else {
// Write the restrictions to XML
- writeApplicationRestrictionsLP(packageName, restrictions, userId);
+ writeApplicationRestrictionsLAr(packageName, restrictions, userId);
}
}
@@ -2894,15 +2895,17 @@
}
}
- private Bundle readApplicationRestrictionsLP(String packageName, int userId) {
+ @GuardedBy("mAppRestrictionsLock")
+ private static Bundle readApplicationRestrictionsLAr(String packageName, int userId) {
AtomicFile restrictionsFile =
new AtomicFile(new File(Environment.getUserSystemDirectory(userId),
packageToRestrictionsFileName(packageName)));
- return readApplicationRestrictionsLP(restrictionsFile);
+ return readApplicationRestrictionsLAr(restrictionsFile);
}
@VisibleForTesting
- static Bundle readApplicationRestrictionsLP(AtomicFile restrictionsFile) {
+ @GuardedBy("mAppRestrictionsLock")
+ static Bundle readApplicationRestrictionsLAr(AtomicFile restrictionsFile) {
final Bundle restrictions = new Bundle();
final ArrayList<String> values = new ArrayList<>();
if (!restrictionsFile.getBaseFile().exists()) {
@@ -2985,16 +2988,18 @@
return childBundle;
}
- private void writeApplicationRestrictionsLP(String packageName,
+ @GuardedBy("mAppRestrictionsLock")
+ private static void writeApplicationRestrictionsLAr(String packageName,
Bundle restrictions, int userId) {
AtomicFile restrictionsFile = new AtomicFile(
new File(Environment.getUserSystemDirectory(userId),
packageToRestrictionsFileName(packageName)));
- writeApplicationRestrictionsLP(restrictions, restrictionsFile);
+ writeApplicationRestrictionsLAr(restrictions, restrictionsFile);
}
@VisibleForTesting
- static void writeApplicationRestrictionsLP(Bundle restrictions, AtomicFile restrictionsFile) {
+ @GuardedBy("mAppRestrictionsLock")
+ static void writeApplicationRestrictionsLAr(Bundle restrictions, AtomicFile restrictionsFile) {
FileOutputStream fos = null;
try {
fos = restrictionsFile.startWrite();
@@ -3238,7 +3243,7 @@
return -1;
}
- private String packageToRestrictionsFileName(String packageName) {
+ private static String packageToRestrictionsFileName(String packageName) {
return RESTRICTIONS_FILE_PREFIX + packageName + XML_SUFFIX;
}
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index 27159fa..bc531c3 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -335,6 +335,7 @@
static public final String SYSTEM_DIALOG_REASON_RECENT_APPS = "recentapps";
static public final String SYSTEM_DIALOG_REASON_HOME_KEY = "homekey";
static public final String SYSTEM_DIALOG_REASON_ASSIST = "assist";
+ static public final String SYSTEM_DIALOG_REASON_SCREENSHOT = "screenshot";
/**
* These are the system UI flags that, when changing, can cause the layout
@@ -829,6 +830,7 @@
private static final int MSG_ACCESSIBILITY_TV = 23;
private static final int MSG_DISPATCH_BACK_KEY_TO_AUTOFILL = 24;
private static final int MSG_SYSTEM_KEY_PRESS = 25;
+ private static final int MSG_HANDLE_ALL_APPS = 26;
private static final int MSG_REQUEST_TRANSIENT_BARS_ARG_STATUS = 0;
private static final int MSG_REQUEST_TRANSIENT_BARS_ARG_NAVIGATION = 1;
@@ -921,6 +923,9 @@
case MSG_SYSTEM_KEY_PRESS:
sendSystemKeyToStatusBar(msg.arg1);
break;
+ case MSG_HANDLE_ALL_APPS:
+ launchAllAppsAction();
+ break;
}
}
}
@@ -1801,6 +1806,17 @@
private void launchAllAppsAction() {
Intent intent = new Intent(Intent.ACTION_ALL_APPS);
+ if (mHasFeatureLeanback) {
+ final PackageManager pm = mContext.getPackageManager();
+ Intent intentLauncher = new Intent(Intent.ACTION_MAIN);
+ intentLauncher.addCategory(Intent.CATEGORY_HOME);
+ ResolveInfo resolveInfo = pm.resolveActivityAsUser(intentLauncher,
+ PackageManager.MATCH_SYSTEM_ONLY,
+ mCurrentUserId);
+ if (resolveInfo != null) {
+ intent.setPackage(resolveInfo.activityInfo.packageName);
+ }
+ }
startActivityAsUser(intent, UserHandle.CURRENT);
}
@@ -3620,6 +3636,14 @@
return -1;
} else if (mHasFeatureLeanback && interceptAccessibilityGestureTv(keyCode, down)) {
return -1;
+ } else if (keyCode == KeyEvent.KEYCODE_ALL_APPS) {
+ if (!down) {
+ mHandler.removeMessages(MSG_HANDLE_ALL_APPS);
+ Message msg = mHandler.obtainMessage(MSG_HANDLE_ALL_APPS);
+ msg.setAsynchronous(true);
+ msg.sendToTarget();
+ }
+ return -1;
}
// Toggle Caps Lock on META-ALT.
diff --git a/services/core/java/com/android/server/search/SearchManagerService.java b/services/core/java/com/android/server/search/SearchManagerService.java
index 8969771..c3fa823 100644
--- a/services/core/java/com/android/server/search/SearchManagerService.java
+++ b/services/core/java/com/android/server/search/SearchManagerService.java
@@ -17,7 +17,6 @@
package com.android.server.search;
import android.app.ActivityManager;
-import android.app.AppGlobals;
import android.app.IActivityManager;
import android.app.ISearchManager;
import android.app.SearchManager;
@@ -26,7 +25,6 @@
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
-import android.content.pm.IPackageManager;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.database.ContentObserver;
@@ -37,6 +35,7 @@
import android.os.UserHandle;
import android.os.UserManager;
import android.provider.Settings;
+import android.service.voice.VoiceInteractionService;
import android.util.Log;
import android.util.SparseArray;
@@ -272,24 +271,25 @@
}
}
+ // Check and return VIS component
private ComponentName getLegacyAssistComponent(int userHandle) {
try {
userHandle = ActivityManager.handleIncomingUser(Binder.getCallingPid(),
- Binder.getCallingUid(), userHandle, true, false, "getLegacyAssistComponent", null);
- IPackageManager pm = AppGlobals.getPackageManager();
- Intent assistIntent = new Intent(Intent.ACTION_ASSIST);
- ResolveInfo info =
- pm.resolveIntent(assistIntent,
- assistIntent.resolveTypeIfNeeded(mContext.getContentResolver()),
- PackageManager.MATCH_DEFAULT_ONLY, userHandle);
- if (info != null) {
+ Binder.getCallingUid(), userHandle, true, false, "getLegacyAssistComponent",
+ null);
+ PackageManager pm = mContext.getPackageManager();
+ Intent intentAssistProbe = new Intent(VoiceInteractionService.SERVICE_INTERFACE);
+ List<ResolveInfo> infoListVis = pm.queryIntentServicesAsUser(intentAssistProbe,
+ PackageManager.MATCH_SYSTEM_ONLY, userHandle);
+ if (infoListVis == null || infoListVis.isEmpty()) {
+ return null;
+ } else {
+ ResolveInfo rInfo = infoListVis.get(0);
return new ComponentName(
- info.activityInfo.applicationInfo.packageName,
- info.activityInfo.name);
+ rInfo.serviceInfo.applicationInfo.packageName,
+ rInfo.serviceInfo.name);
+
}
- } catch (RemoteException re) {
- // Local call
- Log.e(TAG, "RemoteException in getLegacyAssistComponent: " + re);
} catch (Exception e) {
Log.e(TAG, "Exception in getLegacyAssistComponent: " + e);
}
@@ -304,9 +304,15 @@
}
long ident = Binder.clearCallingIdentity();
try {
- Intent intent = new Intent(Intent.ACTION_ASSIST);
+ Intent intent = new Intent(VoiceInteractionService.SERVICE_INTERFACE);
intent.setComponent(comp);
+
IActivityManager am = ActivityManager.getService();
+ if (args != null) {
+ args.putInt(Intent.EXTRA_KEY_EVENT, android.view.KeyEvent.KEYCODE_ASSIST);
+ }
+ intent.putExtras(args);
+
return am.launchAssistIntent(intent, ActivityManager.ASSIST_CONTEXT_BASIC, hint,
userHandle, args);
} catch (RemoteException e) {
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index 0b967b3..fff682c 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -4106,6 +4106,16 @@
private boolean isActivePasswordSufficientForUserLocked(
DevicePolicyData policy, int userHandle, boolean parent) {
+ final int requiredPasswordQuality = getPasswordQuality(null, userHandle, parent);
+ if (requiredPasswordQuality == DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED) {
+ // A special case is when there is no required password quality, then we just return
+ // true since any password would be sufficient. This is for the scenario when a work
+ // profile is first created so there is no information about the current password but
+ // it should be considered sufficient as there is no password requirement either.
+ // This is useful since it short-circuits the password checkpoint for FDE device below.
+ return true;
+ }
+
if (!mInjector.storageManagerIsFileBasedEncryptionEnabled()
&& !policy.mPasswordStateHasBeenSetSinceBoot) {
// Before user enters their password for the first time after a reboot, return the
@@ -4116,7 +4126,6 @@
return policy.mPasswordValidAtLastCheckpoint;
}
- final int requiredPasswordQuality = getPasswordQuality(null, userHandle, parent);
if (policy.mActivePasswordMetrics.quality < requiredPasswordQuality) {
return false;
}
diff --git a/services/tests/servicestests/src/com/android/server/pm/UserManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/pm/UserManagerServiceTest.java
index 9f77297..d136614 100644
--- a/services/tests/servicestests/src/com/android/server/pm/UserManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/UserManagerServiceTest.java
@@ -55,11 +55,11 @@
public void testWriteReadApplicationRestrictions() throws IOException {
AtomicFile atomicFile = new AtomicFile(restrictionsFile);
Bundle bundle = createBundle();
- UserManagerService.writeApplicationRestrictionsLP(bundle, atomicFile);
+ UserManagerService.writeApplicationRestrictionsLAr(bundle, atomicFile);
assertTrue(atomicFile.getBaseFile().exists());
String s = FileUtils.readTextFile(restrictionsFile, 10000, "");
System.out.println("restrictionsFile: " + s);
- bundle = UserManagerService.readApplicationRestrictionsLP(atomicFile);
+ bundle = UserManagerService.readApplicationRestrictionsLAr(atomicFile);
System.out.println("readApplicationRestrictionsLocked bundle: " + bundle);
assertBundle(bundle);
}
diff --git a/telephony/java/android/telephony/PhoneNumberUtils.java b/telephony/java/android/telephony/PhoneNumberUtils.java
index 8705446..d5ff1ad 100644
--- a/telephony/java/android/telephony/PhoneNumberUtils.java
+++ b/telephony/java/android/telephony/PhoneNumberUtils.java
@@ -2540,11 +2540,11 @@
}
// Split a phone number like "+20(123)-456#" using spaces, ignoring anything that is not
- // a digit, to produce a result like "20 123 456".
+ // a digit or the characters * and #, to produce a result like "20 123 456#".
private static String splitAtNonNumerics(CharSequence number) {
StringBuilder sb = new StringBuilder(number.length());
for (int i = 0; i < number.length(); i++) {
- sb.append(PhoneNumberUtils.isISODigit(number.charAt(i))
+ sb.append(PhoneNumberUtils.is12Key(number.charAt(i))
? number.charAt(i)
: " ");
}
diff --git a/tests/net/java/com/android/server/ConnectivityServiceTest.java b/tests/net/java/com/android/server/ConnectivityServiceTest.java
index f6481cf..8816d43 100644
--- a/tests/net/java/com/android/server/ConnectivityServiceTest.java
+++ b/tests/net/java/com/android/server/ConnectivityServiceTest.java
@@ -64,6 +64,7 @@
import android.net.NetworkMisc;
import android.net.NetworkRequest;
import android.net.NetworkSpecifier;
+import android.net.NetworkUtils;
import android.net.RouteInfo;
import android.net.StringNetworkSpecifier;
import android.net.metrics.IpConnectivityLog;
@@ -88,6 +89,7 @@
import android.test.mock.MockContentResolver;
import android.test.suitebuilder.annotation.SmallTest;
import android.text.TextUtils;
+import android.util.ArraySet;
import android.util.Log;
import android.util.LogPrinter;
@@ -109,7 +111,10 @@
import java.net.InetAddress;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Collection;
+import java.util.List;
import java.util.Objects;
+import java.util.Set;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;
@@ -304,6 +309,10 @@
private String mRedirectUrl;
MockNetworkAgent(int transport) {
+ this(transport, new LinkProperties());
+ }
+
+ MockNetworkAgent(int transport, LinkProperties linkProperties) {
final int type = transportToLegacyType(transport);
final String typeName = ConnectivityManager.getNetworkTypeName(type);
mNetworkInfo = new NetworkInfo(type, 0, typeName, "Mock");
@@ -329,7 +338,7 @@
mHandlerThread.start();
mNetworkAgent = new NetworkAgent(mHandlerThread.getLooper(), mServiceContext,
"Mock-" + typeName, mNetworkInfo, mNetworkCapabilities,
- new LinkProperties(), mScore, new NetworkMisc()) {
+ linkProperties, mScore, new NetworkMisc()) {
@Override
public void unwanted() { mDisconnected.open(); }
@@ -3338,6 +3347,68 @@
assertException(() -> { mCm.requestRouteToHostAddress(TYPE_NONE, null); }, unsupported);
}
+ @SmallTest
+ public void testLinkPropertiesEnsuresDirectlyConnectedRoutes() {
+ final NetworkRequest networkRequest = new NetworkRequest.Builder()
+ .addTransportType(TRANSPORT_WIFI).build();
+ final TestNetworkCallback networkCallback = new TestNetworkCallback();
+ mCm.registerNetworkCallback(networkRequest, networkCallback);
+
+ LinkProperties lp = new LinkProperties();
+ lp.setInterfaceName("wlan0");
+ LinkAddress myIpv4Address = new LinkAddress("192.168.12.3/24");
+ RouteInfo myIpv4DefaultRoute = new RouteInfo((IpPrefix) null,
+ NetworkUtils.numericToInetAddress("192.168.12.1"), lp.getInterfaceName());
+ lp.addLinkAddress(myIpv4Address);
+ lp.addRoute(myIpv4DefaultRoute);
+
+ // Verify direct routes are added when network agent is first registered in
+ // ConnectivityService.
+ MockNetworkAgent networkAgent = new MockNetworkAgent(TRANSPORT_WIFI, lp);
+ networkAgent.connect(true);
+ networkCallback.expectCallback(CallbackState.AVAILABLE, networkAgent);
+ networkCallback.expectCallback(CallbackState.NETWORK_CAPABILITIES, networkAgent);
+ CallbackInfo cbi = networkCallback.expectCallback(CallbackState.LINK_PROPERTIES,
+ networkAgent);
+ networkCallback.expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, networkAgent);
+ networkCallback.assertNoCallback();
+ checkDirectlyConnectedRoutes(cbi.arg, Arrays.asList(myIpv4Address),
+ Arrays.asList(myIpv4DefaultRoute));
+ checkDirectlyConnectedRoutes(mCm.getLinkProperties(networkAgent.getNetwork()),
+ Arrays.asList(myIpv4Address), Arrays.asList(myIpv4DefaultRoute));
+
+ // Verify direct routes are added during subsequent link properties updates.
+ LinkProperties newLp = new LinkProperties(lp);
+ LinkAddress myIpv6Address1 = new LinkAddress("fe80::cafe/64");
+ LinkAddress myIpv6Address2 = new LinkAddress("2001:db8::2/64");
+ newLp.addLinkAddress(myIpv6Address1);
+ newLp.addLinkAddress(myIpv6Address2);
+ networkAgent.sendLinkProperties(newLp);
+ cbi = networkCallback.expectCallback(CallbackState.LINK_PROPERTIES, networkAgent);
+ networkCallback.assertNoCallback();
+ checkDirectlyConnectedRoutes(cbi.arg,
+ Arrays.asList(myIpv4Address, myIpv6Address1, myIpv6Address2),
+ Arrays.asList(myIpv4DefaultRoute));
+ mCm.unregisterNetworkCallback(networkCallback);
+ }
+
+ private void checkDirectlyConnectedRoutes(Object callbackObj,
+ Collection<LinkAddress> linkAddresses, Collection<RouteInfo> otherRoutes) {
+ assertTrue(callbackObj instanceof LinkProperties);
+ LinkProperties lp = (LinkProperties) callbackObj;
+
+ Set<RouteInfo> expectedRoutes = new ArraySet<>();
+ expectedRoutes.addAll(otherRoutes);
+ for (LinkAddress address : linkAddresses) {
+ RouteInfo localRoute = new RouteInfo(address, null, lp.getInterfaceName());
+ // Duplicates in linkAddresses are considered failures
+ assertTrue(expectedRoutes.add(localRoute));
+ }
+ List<RouteInfo> observedRoutes = lp.getRoutes();
+ assertEquals(expectedRoutes.size(), observedRoutes.size());
+ assertTrue(observedRoutes.containsAll(expectedRoutes));
+ }
+
private static <T> void assertEmpty(T[] ts) {
int length = ts.length;
assertEquals("expected empty array, but length was " + length, 0, length);