diff options
10 files changed, 176 insertions, 94 deletions
diff --git a/core/java/android/view/animation/AnimationSet.java b/core/java/android/view/animation/AnimationSet.java index def4d70..14d3d19 100644 --- a/core/java/android/view/animation/AnimationSet.java +++ b/core/java/android/view/animation/AnimationSet.java @@ -348,12 +348,13 @@ public class AnimationSet extends Animation { for (int i = count - 1; i >= 0; --i) { final Animation a = animations.get(i); - - temp.clear(); - final Interpolator interpolator = a.mInterpolator; - a.applyTransformation(interpolator != null ? interpolator.getInterpolation(0.0f) - : 0.0f, temp); - previousTransformation.compose(temp); + if (!a.isFillEnabled() || a.getFillBefore() || a.getStartOffset() == 0) { + temp.clear(); + final Interpolator interpolator = a.mInterpolator; + a.applyTransformation(interpolator != null ? interpolator.getInterpolation(0.0f) + : 0.0f, temp); + previousTransformation.compose(temp); + } } } } diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java index baa7c0f..fa82c46 100644 --- a/core/java/android/webkit/WebView.java +++ b/core/java/android/webkit/WebView.java @@ -1012,10 +1012,19 @@ public class WebView extends AbsoluteLayout mExtra = extra; } + /** + * Gets the type of the hit test result. + * @return See the XXX_TYPE constants defined in this class. + */ public int getType() { return mType; } + /** + * Gets additional type-dependant information about the result, see + * {@link WebView#getHitTestResult()} for details. + * @return may either be null or contain extra information about this result. + */ public String getExtra() { return mExtra; } @@ -1053,6 +1062,7 @@ public class WebView extends AbsoluteLayout * @param context A Context object used to access application assets. * @param attrs An AttributeSet passed to our parent. * @param defStyle The default style resource ID. + * @param privateBrowsing If true the web view will be initialized in private mode. */ public WebView(Context context, AttributeSet attrs, int defStyle, boolean privateBrowsing) { @@ -1069,6 +1079,7 @@ public class WebView extends AbsoluteLayout * @param defStyle The default style resource ID. * @param javaScriptInterfaces is a Map of interface names, as keys, and * object implementing those interfaces, as values. + * @param privateBrowsing If true the web view will be initialized in private mode. * @hide This is an implementation detail. */ protected WebView(Context context, AttributeSet attrs, int defStyle, @@ -5706,6 +5717,7 @@ public class WebView extends AbsoluteLayout * @deprecated WebView no longer needs to implement * ViewGroup.OnHierarchyChangeListener. This method does nothing now. */ + // Cannot add @hide as this can always be accessed via the interface. @Deprecated public void onChildViewAdded(View parent, View child) {} @@ -5713,6 +5725,7 @@ public class WebView extends AbsoluteLayout * @deprecated WebView no longer needs to implement * ViewGroup.OnHierarchyChangeListener. This method does nothing now. */ + // Cannot add @hide as this can always be accessed via the interface. @Deprecated public void onChildViewRemoved(View p, View child) {} @@ -5720,6 +5733,7 @@ public class WebView extends AbsoluteLayout * @deprecated WebView should not have implemented * ViewTreeObserver.OnGlobalFocusChangeListener. This method does nothing now. */ + // Cannot add @hide as this can always be accessed via the interface. @Deprecated public void onGlobalFocusChanged(View oldFocus, View newFocus) { } diff --git a/docs/html/guide/topics/appwidgets/index.jd b/docs/html/guide/topics/appwidgets/index.jd index 2cb23c1..7b869a0 100644 --- a/docs/html/guide/topics/appwidgets/index.jd +++ b/docs/html/guide/topics/appwidgets/index.jd @@ -186,36 +186,34 @@ folder.</p> <p>Here's a summary of the <code><appwidget-provider></code> attributes:</p> <ul> <li>The values for the <code>minWidth</code> and <code>minHeight</code> -attributes specify the minimum - area required by the App Widget's layout. - <p>The default Home screen positions App Widgets in its window based on a -grid of - cells that have a defined height and width. If the values for an App -Widget's minimum width - or height don't match the dimensions of the cells, - then the App Widget dimensions round <em>up</em> to the nearest cell size. - (See the <a -href="{@docRoot}guide/practices/ui_guidelines/widget_design.html">App Widget -Design - Guidelines</a> for more information on the Home screen cell sizes.)</p> - <p>Because the Home screen's layout orientation (and thus, the cell sizes) -can change, - as a rule of thumb, you should assume the worst-case cell size of 74 pixels -for the height - <em>and</em> width of a cell. However, you must subtract 2 from the final -dimension to account - for any integer rounding errors that occur in the pixel count. To find your -minimum width - and height in density-independent pixels (dp), use this formula:<br/> - <code>(number of cells * 74) - 2</code><br/> - Following this formula, you should use 72 dp for a height of one cell, 294 -dp and for a width of four cells.</p> -<p class="note"><strong>Note:</strong> To make your app widget portable across -devices, your app widget's minimum size should never be larger than 4 x 4 cells. -See the <a -href="{@docRoot}guide/practices/ui_guidelines/widget_design.html#sizes">App -Widget Design Guidelines</a> for more discussion of Home screen cell sizes.</p> + attributes specify the minimum amount of space the App Widget consumes + <em>by default</em>. The default Home screen positions App Widgets in its + window based on a grid of cells that have a defined height and width. If + the values for an App Widget's minimum width or height don't match the + dimensions of the cells, then the App Widget dimensions round + <em>up</em> to the nearest cell size. + <p>See the <a href="{@docRoot}guide/practices/ui_guidelines/widget_design.html#anatomy_determining_size"> + App Widget Design Guidelines</a> for more information on sizing your App + Widgets.</p> + + <p class="note"><strong>Note:</strong> To make your app widget portable + across devices, your app widget's minimum size should never be larger + than 4 x 4 cells.</p> </li> + + <li>The <code>minResizeWidth</code> and <code>minResizeHeight</code> attributes + specify the App Widget's absolute minimum size. These values should specify + the size below which the App Widget would be illegible or otherwise unusable. + Using these attributes allows the user to resize the widget to a size that + may be smaller than the default widget size defined by the + <code>minWidth</code> and <code>minHeight</code> attributes. + Introduced in Android 3.1. + + <p>See the <a href="{@docRoot}guide/practices/ui_guidelines/widget_design.html#anatomy_determining_size"> + App Widget Design Guidelines</a> for more information on sizing your App + Widgets.</p> + </li> + <li>The <code>updatePeriodMillis</code> attribute defines how often the App Widget framework should request an update from the {@link android.appwidget.AppWidgetProvider} by calling the diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmDataConnection.java b/telephony/java/com/android/internal/telephony/gsm/GsmDataConnection.java index 1f24b58..dbb35f2 100644 --- a/telephony/java/com/android/internal/telephony/gsm/GsmDataConnection.java +++ b/telephony/java/com/android/internal/telephony/gsm/GsmDataConnection.java @@ -36,7 +36,6 @@ public class GsmDataConnection extends DataConnection { //***** Instance Variables protected int mProfileId = RILConstants.DATA_PROFILE_DEFAULT; - protected String mActiveApnType = Phone.APN_TYPE_DEFAULT; //***** Constructor private GsmDataConnection(PhoneBase phone, String name, int id, RetryManager rm) { super(phone, name, id, rm); @@ -113,10 +112,6 @@ public class GsmDataConnection extends DataConnection { return mProfileId; } - public void setActiveApnType(String apnType) { - mActiveApnType = apnType; - } - @Override public String toString() { return "State=" + getCurrentState().getName() + " Apn=" + mApn + diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java b/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java index 963db2c..fd85642 100644 --- a/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java +++ b/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java @@ -993,17 +993,11 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker { return false; } - // First, check to see if ApnContext already has DC. - // This could happen if the retries are currently engaged. - dc = (GsmDataConnection)apnContext.getDataConnection(); - if (dc == null) { - - dc = (GsmDataConnection) checkForConnectionForApnContext(apnContext); + dc = (GsmDataConnection) checkForConnectionForApnContext(apnContext); - if (dc == null) { - dc = findReadyDataConnection(apn); - } + if (dc == null) { + dc = findReadyDataConnection(apn); if (dc == null) { if (DBG) log("setupData: No ready GsmDataConnection found!"); @@ -1020,20 +1014,22 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker { if (DBG) log("setupData: No free GsmDataConnection found!"); return false; } + } else { + apn = mDataConnectionAsyncChannels.get(dc.getDataConnectionId()).getApnSettingSync(); + } - DataConnectionAc dcac = mDataConnectionAsyncChannels.get(dc.getDataConnectionId()); - dc.setProfileId( profileId ); - dc.setActiveApnType(apnContext.getApnType()); - int refCount = dcac.getRefCountSync(); - if (DBG) log("setupData: init dc and apnContext refCount=" + refCount); + DataConnectionAc dcac = mDataConnectionAsyncChannels.get(dc.getDataConnectionId()); + dc.setProfileId( profileId ); // assumed no connection sharing on profiled types - // configure retry count if no other Apn is using the same connection. - if (refCount == 0) { - configureRetry(dc, apn.canHandleType(Phone.APN_TYPE_DEFAULT)); - } - apnContext.setDataConnectionAc(dcac); - apnContext.setDataConnection(dc); + int refCount = dcac.getRefCountSync(); + if (DBG) log("setupData: init dc and apnContext refCount=" + refCount); + + // configure retry count if no other Apn is using the same connection. + if (refCount == 0) { + configureRetry(dc, apn.canHandleType(Phone.APN_TYPE_DEFAULT)); } + apnContext.setDataConnectionAc(dcac); + apnContext.setDataConnection(dc); apnContext.setApnSetting(apn); apnContext.setState(State.INITING); @@ -1732,27 +1728,46 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker { dunSetting = fetchDunApn(); } + DataConnection potential = null; for (ApnContext c : mApnContexts.values()) { DataConnection conn = c.getDataConnection(); if (conn != null) { ApnSetting apnSetting = c.getApnSetting(); if (dunSetting != null) { if (dunSetting.equals(apnSetting)) { - if (DBG) { - log("checkForConnectionForApnContext: apnContext=" + apnContext + - " found conn=" + conn); + switch (c.getState()) { + case CONNECTED: + if (DBG) { + log("checkForConnectionForApnContext: apnContext=" + + apnContext + " found conn=" + conn); + } + return conn; + case CONNECTING: + potential = conn; } - return conn; } } else if (apnSetting != null && apnSetting.canHandleType(apnType)) { - if (DBG) { - log("checkForConnectionForApnContext: apnContext=" + apnContext + - " found conn=" + conn); + switch (c.getState()) { + case CONNECTED: + if (DBG) { + log("checkForConnectionForApnContext: apnContext=" + apnContext + + " found conn=" + conn); + } + return conn; + case CONNECTING: + potential = conn; } - return conn; } } } + if (potential != null) { + if (DBG) { + log("checkForConnectionForApnContext: apnContext=" + apnContext + + " found conn=" + potential); + } + return potential; + } + if (DBG) log("checkForConnectionForApnContext: apnContext=" + apnContext + " NO conn"); return null; } diff --git a/wifi/java/android/net/wifi/WifiMonitor.java b/wifi/java/android/net/wifi/WifiMonitor.java index 80963a8..05b8fe1 100644 --- a/wifi/java/android/net/wifi/WifiMonitor.java +++ b/wifi/java/android/net/wifi/WifiMonitor.java @@ -196,7 +196,7 @@ public class WifiMonitor { private static final String P2P_PROV_DISC_SHOW_PIN_STR = "P2P-PROV-DISC-SHOW-PIN"; private static final String HOST_AP_EVENT_PREFIX_STR = "AP"; - /* AP-STA-CONNECTED 42:fc:89:a8:96:09 */ + /* AP-STA-CONNECTED 42:fc:89:a8:96:09 dev_addr=02:90:4c:a0:92:54 */ private static final String AP_STA_CONNECTED_STR = "AP-STA-CONNECTED"; /* AP-STA-DISCONNECTED 42:fc:89:a8:96:09 */ private static final String AP_STA_DISCONNECTED_STR = "AP-STA-DISCONNECTED"; @@ -504,9 +504,17 @@ public class WifiMonitor { */ private void handleHostApEvents(String dataString) { String[] tokens = dataString.split(" "); + /* AP-STA-CONNECTED 42:fc:89:a8:96:09 dev_addr=02:90:4c:a0:92:54 */ if (tokens[0].equals(AP_STA_CONNECTED_STR)) { - mStateMachine.sendMessage(AP_STA_CONNECTED_EVENT, tokens[1]); + String[] nameValue = tokens[2].split("="); + if (nameValue.length != 2) return; + WifiP2pDevice device = new WifiP2pDevice(); + device.interfaceAddress = tokens[1]; + device.deviceAddress = nameValue[1]; + mStateMachine.sendMessage(AP_STA_CONNECTED_EVENT, device); + /* AP-STA-DISCONNECTED 42:fc:89:a8:96:09 */ } else if (tokens[0].equals(AP_STA_DISCONNECTED_STR)) { + //TODO: fix this once wpa_supplicant reports this consistently mStateMachine.sendMessage(AP_STA_DISCONNECTED_EVENT, tokens[1]); } } diff --git a/wifi/java/android/net/wifi/WifiNative.java b/wifi/java/android/net/wifi/WifiNative.java index 0fc0a45..4c06558 100644 --- a/wifi/java/android/net/wifi/WifiNative.java +++ b/wifi/java/android/net/wifi/WifiNative.java @@ -307,9 +307,11 @@ public class WifiNative { if (joinExistingGroup) args.add("join"); + //TODO: This can be adapted based on device plugged in state and + //device battery state int groupOwnerIntent = config.groupOwnerIntent; if (groupOwnerIntent < 0 || groupOwnerIntent > 15) { - groupOwnerIntent = 3; //default value + groupOwnerIntent = 7; //default value } args.add("go_intent=" + groupOwnerIntent); diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pDevice.java b/wifi/java/android/net/wifi/p2p/WifiP2pDevice.java index b47e098..7471a2d 100644 --- a/wifi/java/android/net/wifi/p2p/WifiP2pDevice.java +++ b/wifi/java/android/net/wifi/p2p/WifiP2pDevice.java @@ -34,12 +34,12 @@ public class WifiP2pDevice implements Parcelable { /** * The device name is a user friendly string to identify a Wi-Fi p2p device */ - public String deviceName; + public String deviceName = ""; /** * The device MAC address uniquely identifies a Wi-Fi p2p device */ - public String deviceAddress; + public String deviceAddress = ""; /** * interfaceAddress @@ -134,7 +134,7 @@ public class WifiP2pDevice implements Parcelable { * @hide */ public WifiP2pDevice(String string) throws IllegalArgumentException { - String[] tokens = string.split(" "); + String[] tokens = string.split("[ \n]"); if (tokens.length < 1) { throw new IllegalArgumentException("Malformed supplicant event"); @@ -166,7 +166,7 @@ public class WifiP2pDevice implements Parcelable { continue; } - if (nameValue[0].equals("name")) { + if (nameValue[0].equals("name") || nameValue[0].equals("device_name")) { deviceName = trimQuotes(nameValue[1]); continue; } diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pDeviceList.java b/wifi/java/android/net/wifi/p2p/WifiP2pDeviceList.java index 9ce2545..cbb4e81 100644 --- a/wifi/java/android/net/wifi/p2p/WifiP2pDeviceList.java +++ b/wifi/java/android/net/wifi/p2p/WifiP2pDeviceList.java @@ -80,6 +80,19 @@ public class WifiP2pDeviceList implements Parcelable { } /** @hide */ + public void updateInterfaceAddress(WifiP2pDevice device) { + for (WifiP2pDevice d : mDevices) { + //Found, update interface address + if (d.equals(device)) { + d.interfaceAddress = device.interfaceAddress; + return; + } + } + //Not found, add a new one + mDevices.add(device); + } + + /** @hide */ public boolean remove(WifiP2pDevice device) { if (device == null) return false; return mDevices.remove(device); diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pService.java b/wifi/java/android/net/wifi/p2p/WifiP2pService.java index dede1b5..84a4fe0 100644 --- a/wifi/java/android/net/wifi/p2p/WifiP2pService.java +++ b/wifi/java/android/net/wifi/p2p/WifiP2pService.java @@ -727,6 +727,8 @@ public class WifiP2pService extends IWifiP2pManager.Stub { case WifiP2pManager.CONNECT: if (DBG) logd(getName() + " sending connect"); mSavedPeerConfig = (WifiP2pConfig) message.obj; + String updatedPeerDetails = WifiNative.p2pPeer(mSavedPeerConfig.deviceAddress); + mPeers.update(new WifiP2pDevice(updatedPeerDetails)); mPersistGroup = false; int netId = configuredNetworkId(mSavedPeerConfig.deviceAddress); if (netId >= 0) { @@ -736,13 +738,7 @@ public class WifiP2pService extends IWifiP2pManager.Stub { //If peer is a GO, we do not need to send provisional discovery, //the supplicant takes care of it. if (isGroupOwner(mSavedPeerConfig.deviceAddress)) { - String pin = WifiNative.p2pConnect(mSavedPeerConfig, JOIN_GROUP); - try { - Integer.parseInt(pin); - notifyInvitationSent(pin, mSavedPeerConfig.deviceAddress); - } catch (NumberFormatException ignore) { - // do nothing if p2pConnect did not return a pin - } + p2pConnectWithPinDisplay(mSavedPeerConfig, JOIN_GROUP); transitionTo(mGroupNegotiationState); } else { transitionTo(mProvisionDiscoveryState); @@ -758,8 +754,27 @@ public class WifiP2pService extends IWifiP2pManager.Stub { break; case WifiMonitor.P2P_INVITATION_RECEIVED_EVENT: WifiP2pGroup group = (WifiP2pGroup) message.obj; - //TODO: fix p2p invitation to handle as a regular config - //and update mSavedPeerConfig + WifiP2pDevice owner = group.getOwner(); + + if (owner == null) { + if (DBG) loge("Ignored invitation from null owner"); + break; + } + + mSavedPeerConfig = new WifiP2pConfig(); + mSavedPeerConfig.deviceAddress = group.getOwner().deviceAddress; + + //Check if we have the owner in peer list and use appropriate + //wps method. Default is to use PBC. + if ((owner = getDeviceFromPeerList(owner.deviceAddress)) != null) { + if (owner.wpsPbcSupported()) { + mSavedPeerConfig.wps.setup = WpsInfo.PBC; + } else if (owner.wpsKeypadSupported()) { + mSavedPeerConfig.wps.setup = WpsInfo.KEYPAD; + } else if (owner.wpsDisplaySupported()) { + mSavedPeerConfig.wps.setup = WpsInfo.DISPLAY; + } + } transitionTo(mUserAuthorizingInvitationState); break; case WifiMonitor.P2P_PROV_DISC_PBC_REQ_EVENT: @@ -853,9 +868,9 @@ public class WifiP2pService extends IWifiP2pManager.Stub { case PEER_CONNECTION_USER_ACCEPT: //TODO: handle persistence if (isGroupOwner(mSavedPeerConfig.deviceAddress)) { - WifiNative.p2pConnect(mSavedPeerConfig, JOIN_GROUP); + p2pConnectWithPinDisplay(mSavedPeerConfig, JOIN_GROUP); } else { - WifiNative.p2pConnect(mSavedPeerConfig, FORM_GROUP); + p2pConnectWithPinDisplay(mSavedPeerConfig, FORM_GROUP); } updateDeviceStatus(mSavedPeerConfig.deviceAddress, WifiP2pDevice.INVITED); sendP2pPeersChangedBroadcast(); @@ -1007,20 +1022,22 @@ public class WifiP2pService extends IWifiP2pManager.Stub { if (DBG) logd(getName() + message.toString()); switch (message.what) { case WifiMonitor.AP_STA_CONNECTED_EVENT: - //After a GO setup, STA connected event comes with interface address - String interfaceAddress = (String) message.obj; - String deviceAddress = getDeviceAddress(interfaceAddress); + WifiP2pDevice device = (WifiP2pDevice) message.obj; + String deviceAddress = device.deviceAddress; if (deviceAddress != null) { mGroup.addClient(deviceAddress); + mPeers.updateInterfaceAddress(device); updateDeviceStatus(deviceAddress, WifiP2pDevice.CONNECTED); if (DBG) logd(getName() + " ap sta connected"); sendP2pPeersChangedBroadcast(); } else { - loge("Connect on unknown device address : " + interfaceAddress); + loge("Connect on null device address, ignore"); } break; case WifiMonitor.AP_STA_DISCONNECTED_EVENT: - interfaceAddress = (String) message.obj; + //TODO: the disconnection event is still inconsistent and reports + //interface address. Fix this after wpa_supplicant is fixed. + String interfaceAddress = (String) message.obj; deviceAddress = getDeviceAddress(interfaceAddress); if (deviceAddress != null) { updateDeviceStatus(deviceAddress, WifiP2pDevice.AVAILABLE); @@ -1039,7 +1056,7 @@ public class WifiP2pService extends IWifiP2pManager.Stub { sendP2pPeersChangedBroadcast(); if (DBG) loge(getName() + " ap sta disconnected"); } else { - loge("Disconnect on unknown device address : " + interfaceAddress); + loge("Disconnect on unknown interface address : " + interfaceAddress); } break; case DhcpStateMachine.CMD_POST_DHCP_ACTION: @@ -1087,7 +1104,7 @@ public class WifiP2pService extends IWifiP2pManager.Stub { transitionTo(mInactiveState); break; case WifiMonitor.P2P_DEVICE_LOST_EVENT: - WifiP2pDevice device = (WifiP2pDevice) message.obj; + device = (WifiP2pDevice) message.obj; //Device loss for a connected device indicates it is not in discovery any more if (mGroup.contains(device)) { if (DBG) logd("Lost " + device +" , do nothing"); @@ -1388,13 +1405,32 @@ public class WifiP2pService extends IWifiP2pManager.Stub { private String getDeviceAddress(String interfaceAddress) { for (WifiP2pDevice d : mPeers.getDeviceList()) { - if (interfaceAddress.equals(WifiNative.p2pGetInterfaceAddress(d.deviceAddress))) { + if (interfaceAddress.equals(d.interfaceAddress)) { return d.deviceAddress; } } return null; } + private WifiP2pDevice getDeviceFromPeerList(String deviceAddress) { + for (WifiP2pDevice d : mPeers.getDeviceList()) { + if (d.deviceAddress.equals(deviceAddress)) { + return d; + } + } + return null; + } + + private void p2pConnectWithPinDisplay(WifiP2pConfig config, boolean join) { + String pin = WifiNative.p2pConnect(config, join); + try { + Integer.parseInt(pin); + notifyInvitationSent(pin, config.deviceAddress); + } catch (NumberFormatException ignore) { + // do nothing if p2pConnect did not return a pin + } + } + private void initializeP2pSettings() { WifiNative.setPersistentReconnect(true); WifiNative.setDeviceName(mThisDevice.deviceName); |
