Merge commit 'ec3e9805dd7c527f961d1f2a14e5752b461186ca' into fix-merge-conflict
Conflicts:
wifi/java/android/net/wifi/WifiConfiguration.java
Change-Id: If52be614cadf80955025097589f922072363e7ba
diff --git a/Android.mk b/Android.mk
index b77c2ed..1a6b8cc 100644
--- a/Android.mk
+++ b/Android.mk
@@ -329,6 +329,12 @@
media/java/android/media/projection/IMediaProjectionCallback.aidl \
media/java/android/media/projection/IMediaProjectionManager.aidl \
media/java/android/media/projection/IMediaProjectionWatcherCallback.aidl \
+ media/java/android/media/routing/IMediaRouteService.aidl \
+ media/java/android/media/routing/IMediaRouteClientCallback.aidl \
+ media/java/android/media/routing/IMediaRouter.aidl \
+ media/java/android/media/routing/IMediaRouterDelegate.aidl \
+ media/java/android/media/routing/IMediaRouterRoutingCallback.aidl \
+ media/java/android/media/routing/IMediaRouterStateCallback.aidl \
media/java/android/media/session/IActiveSessionsListener.aidl \
media/java/android/media/session/ISessionController.aidl \
media/java/android/media/session/ISessionControllerCallback.aidl \
@@ -372,10 +378,12 @@
telephony/java/com/android/internal/telephony/ITelephony.aidl \
telephony/java/com/android/internal/telephony/ITelephonyRegistry.aidl \
telephony/java/com/android/internal/telephony/ISms.aidl \
+ telephony/java/com/android/internal/telephony/ISubscriptionListener.aidl \
telephony/java/com/android/internal/telephony/IWapPushManager.aidl \
telephony/java/com/android/internal/telephony/ISub.aidl \
telephony/java/com/android/internal/telephony/IMms.aidl \
wifi/java/android/net/wifi/IWifiManager.aidl \
+ wifi/java/android/net/wifi/passpoint/IWifiPasspointManager.aidl \
wifi/java/android/net/wifi/p2p/IWifiP2pManager.aidl \
wifi/java/android/net/wifi/IWifiScanner.aidl \
wifi/java/android/net/wifi/IRttManager.aidl \
@@ -423,6 +431,7 @@
aidl_files := \
frameworks/base/telephony/java/android/telephony/ServiceState.aidl \
+ frameworks/base/telephony/java/android/telephony/SubInfoRecord.aidl \
frameworks/base/telephony/java/android/telephony/CellInfo.aidl \
frameworks/base/telephony/java/android/telephony/SignalStrength.aidl \
frameworks/base/telephony/java/android/telephony/IccOpenLogicalChannelResponse.aidl \
@@ -432,6 +441,7 @@
frameworks/base/location/java/android/location/Criteria.aidl \
frameworks/base/media/java/android/media/MediaMetadata.aidl \
frameworks/base/media/java/android/media/MediaDescription.aidl \
+ frameworks/base/media/java/android/media/routing/MediaRouteSelector.aidl \
frameworks/base/media/java/android/media/Rating.aidl \
frameworks/base/media/java/android/media/AudioAttributes.aidl \
frameworks/base/media/java/android/media/session/PlaybackState.aidl \
@@ -559,6 +569,7 @@
frameworks/base/core/java/android/content/pm/ProviderInfo.aidl \
frameworks/base/core/java/android/content/pm/PackageStats.aidl \
frameworks/base/core/java/android/content/pm/PermissionGroupInfo.aidl \
+ frameworks/base/core/java/android/content/pm/LabeledIntent.aidl \
frameworks/base/core/java/android/content/ComponentName.aidl \
frameworks/base/core/java/android/content/SyncStats.aidl \
frameworks/base/core/java/android/content/ContentValues.aidl \
@@ -576,7 +587,7 @@
frameworks/base/core/java/android/bluetooth/le/ScanFilter.aidl \
frameworks/base/core/java/android/bluetooth/le/ScanResult.aidl \
frameworks/base/core/java/android/bluetooth/BluetoothDevice.aidl \
- frameworks/base/core/java/android/database/CursorWindow.aidl
+ frameworks/base/core/java/android/database/CursorWindow.aidl \
gen := $(TARGET_OUT_COMMON_INTERMEDIATES)/framework.aidl
$(gen): PRIVATE_SRC_FILES := $(aidl_files)
diff --git a/api/current.txt b/api/current.txt
index 7df6e6e..8dd1323 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -23,6 +23,7 @@
field public static final java.lang.String BIND_DEVICE_ADMIN = "android.permission.BIND_DEVICE_ADMIN";
field public static final java.lang.String BIND_DREAM_SERVICE = "android.permission.BIND_DREAM_SERVICE";
field public static final java.lang.String BIND_INPUT_METHOD = "android.permission.BIND_INPUT_METHOD";
+ field public static final java.lang.String BIND_MEDIA_ROUTE_SERVICE = "android.permission.BIND_MEDIA_ROUTE_SERVICE";
field public static final java.lang.String BIND_NFC_SERVICE = "android.permission.BIND_NFC_SERVICE";
field public static final java.lang.String BIND_NOTIFICATION_LISTENER_SERVICE = "android.permission.BIND_NOTIFICATION_LISTENER_SERVICE";
field public static final java.lang.String BIND_PRINT_SERVICE = "android.permission.BIND_PRINT_SERVICE";
@@ -475,6 +476,7 @@
field public static final int dialogLayout = 16843255; // 0x10101f7
field public static final int dialogMessage = 16843251; // 0x10101f3
field public static final int dialogPreferenceStyle = 16842897; // 0x1010091
+ field public static final int dialogPreferredPadding = 16844037; // 0x1010505
field public static final int dialogTheme = 16843528; // 0x1010308
field public static final int dialogTitle = 16843250; // 0x10101f2
field public static final int digits = 16843110; // 0x1010166
@@ -3303,6 +3305,7 @@
method public final android.app.Activity getParent();
method public android.content.Intent getParentActivityIntent();
method public android.content.SharedPreferences getPreferences(int);
+ method public android.net.Uri getReferrer();
method public int getRequestedOrientation();
method public int getTaskId();
method public final java.lang.CharSequence getTitle();
@@ -7750,6 +7753,7 @@
field public static final java.lang.String EXTRA_ORIGINATING_URI = "android.intent.extra.ORIGINATING_URI";
field public static final java.lang.String EXTRA_PHONE_NUMBER = "android.intent.extra.PHONE_NUMBER";
field public static final java.lang.String EXTRA_REFERRER = "android.intent.extra.REFERRER";
+ field public static final java.lang.String EXTRA_REFERRER_NAME = "android.intent.extra.REFERRER_NAME";
field public static final java.lang.String EXTRA_REMOTE_INTENT_TOKEN = "android.intent.extra.remote_intent_token";
field public static final java.lang.String EXTRA_REPLACEMENT_EXTRAS = "android.intent.extra.REPLACEMENT_EXTRAS";
field public static final java.lang.String EXTRA_REPLACING = "android.intent.extra.REPLACING";
@@ -7809,6 +7813,7 @@
field public static final int FLAG_RECEIVER_REGISTERED_ONLY = 1073741824; // 0x40000000
field public static final int FLAG_RECEIVER_REPLACE_PENDING = 536870912; // 0x20000000
field public static final java.lang.String METADATA_DOCK_HOME = "android.dock_home";
+ field public static final int URI_ANDROID_APP_SCHEME = 2; // 0x2
field public static final int URI_INTENT_SCHEME = 1; // 0x1
}
@@ -14585,6 +14590,7 @@
field public static final int COLOR_Format24bitBGR888 = 12; // 0xc
field public static final int COLOR_Format24bitRGB888 = 11; // 0xb
field public static final int COLOR_Format25bitARGB1888 = 14; // 0xe
+ field public static final int COLOR_Format32BitRGBA8888 = 2130747392; // 0x7f00a000
field public static final int COLOR_Format32bitARGB8888 = 16; // 0x10
field public static final int COLOR_Format32bitBGRA8888 = 15; // 0xf
field public static final int COLOR_Format8bitRGB332 = 2; // 0x2
@@ -16232,11 +16238,248 @@
}
+package android.media.routing {
+
+ public final class MediaRouteSelector implements android.os.Parcelable {
+ method public boolean containsProtocol(java.lang.Class<?>);
+ method public boolean containsProtocol(java.lang.String);
+ method public int describeContents();
+ method public android.os.Bundle getExtras();
+ method public int getOptionalFeatures();
+ method public java.util.List<java.lang.String> getOptionalProtocols();
+ method public int getRequiredFeatures();
+ method public java.util.List<java.lang.String> getRequiredProtocols();
+ method public java.lang.String getServicePackageName();
+ method public void writeToParcel(android.os.Parcel, int);
+ field public static final android.os.Parcelable.Creator<android.media.routing.MediaRouteSelector> CREATOR;
+ }
+
+ public static final class MediaRouteSelector.Builder {
+ ctor public MediaRouteSelector.Builder();
+ method public android.media.routing.MediaRouteSelector.Builder addOptionalProtocol(java.lang.Class<?>);
+ method public android.media.routing.MediaRouteSelector.Builder addOptionalProtocol(java.lang.String);
+ method public android.media.routing.MediaRouteSelector.Builder addRequiredProtocol(java.lang.Class<?>);
+ method public android.media.routing.MediaRouteSelector.Builder addRequiredProtocol(java.lang.String);
+ method public android.media.routing.MediaRouteSelector build();
+ method public android.media.routing.MediaRouteSelector.Builder setExtras(android.os.Bundle);
+ method public android.media.routing.MediaRouteSelector.Builder setOptionalFeatures(int);
+ method public android.media.routing.MediaRouteSelector.Builder setRequiredFeatures(int);
+ method public android.media.routing.MediaRouteSelector.Builder setServicePackageName(java.lang.String);
+ }
+
+ public abstract class MediaRouteService extends android.app.Service {
+ ctor public MediaRouteService();
+ method public android.media.routing.MediaRouter.ServiceMetadata getServiceMetadata();
+ method public android.os.IBinder onBind(android.content.Intent);
+ method public abstract android.media.routing.MediaRouteService.ClientSession onCreateClientSession(android.media.routing.MediaRouteService.ClientInfo);
+ field public static final java.lang.String SERVICE_INTERFACE = "android.media.routing.MediaRouteService";
+ }
+
+ public static final class MediaRouteService.ClientInfo {
+ method public java.lang.String getPackageName();
+ method public int getUid();
+ }
+
+ public static abstract class MediaRouteService.ClientSession {
+ ctor public MediaRouteService.ClientSession();
+ method public abstract boolean onConnect(android.media.routing.MediaRouter.ConnectionRequest, android.media.routing.MediaRouteService.ConnectionCallback);
+ method public abstract void onDisconnect();
+ method public void onPauseStream();
+ method public void onRelease();
+ method public void onResumeStream();
+ method public abstract boolean onStartDiscovery(android.media.routing.MediaRouter.DiscoveryRequest, android.media.routing.MediaRouteService.DiscoveryCallback);
+ method public abstract void onStopDiscovery();
+ }
+
+ public final class MediaRouteService.ConnectionCallback {
+ method public void onConnected(android.media.routing.MediaRouter.ConnectionInfo);
+ method public void onConnectionFailed(int, java.lang.CharSequence, android.os.Bundle);
+ method public void onDisconnected();
+ }
+
+ public final class MediaRouteService.DiscoveryCallback {
+ method public void onDestinationFound(android.media.routing.MediaRouter.DestinationInfo, java.util.List<android.media.routing.MediaRouter.RouteInfo>);
+ method public void onDestinationLost(android.media.routing.MediaRouter.DestinationInfo);
+ method public void onDiscoveryFailed(int, java.lang.CharSequence, android.os.Bundle);
+ }
+
+ public final class MediaRouter {
+ ctor public MediaRouter(android.content.Context);
+ method public void addSelector(android.media.routing.MediaRouteSelector);
+ method public void clearSelectors();
+ method public android.media.routing.MediaRouter.Delegate createDelegate();
+ method public android.media.routing.MediaRouter.ConnectionInfo getConnection();
+ method public int getConnectionState();
+ method public java.util.List<android.media.routing.MediaRouter.DestinationInfo> getDiscoveredDestinations();
+ method public java.util.List<android.media.routing.MediaRouter.RouteInfo> getDiscoveredRoutes(android.media.routing.MediaRouter.DestinationInfo);
+ method public int getDiscoveryState();
+ method public android.media.AudioAttributes getPreferredAudioAttributes();
+ method public android.view.Display getPreferredPresentationDisplay();
+ method public android.media.VolumeProvider getPreferredVolumeProvider();
+ method public android.media.routing.MediaRouter.DestinationInfo getSelectedDestination();
+ method public android.media.routing.MediaRouter.RouteInfo getSelectedRoute();
+ method public java.util.List<android.media.routing.MediaRouteSelector> getSelectors();
+ method public boolean isReleased();
+ method public void pauseStream();
+ method public void release();
+ method public void removeSelector(android.media.routing.MediaRouteSelector);
+ method public void resumeStream();
+ method public void setRoutingCallback(android.media.routing.MediaRouter.RoutingCallback, android.os.Handler);
+ field public static final int CONNECTION_ERROR_ABORTED = 1; // 0x1
+ field public static final int CONNECTION_ERROR_BARGED = 7; // 0x7
+ field public static final int CONNECTION_ERROR_BROKEN = 6; // 0x6
+ field public static final int CONNECTION_ERROR_BUSY = 4; // 0x4
+ field public static final int CONNECTION_ERROR_TIMEOUT = 5; // 0x5
+ field public static final int CONNECTION_ERROR_UNAUTHORIZED = 2; // 0x2
+ field public static final int CONNECTION_ERROR_UNKNOWN = 0; // 0x0
+ field public static final int CONNECTION_ERROR_UNREACHABLE = 3; // 0x3
+ field public static final int CONNECTION_FLAG_BARGE = 1; // 0x1
+ field public static final int CONNECTION_STATE_CONNECTED = 2; // 0x2
+ field public static final int CONNECTION_STATE_CONNECTING = 1; // 0x1
+ field public static final int CONNECTION_STATE_DISCONNECTED = 0; // 0x0
+ field public static final int DISCONNECTION_REASON_APPLICATION_REQUEST = 0; // 0x0
+ field public static final int DISCONNECTION_REASON_ERROR = 2; // 0x2
+ field public static final int DISCONNECTION_REASON_USER_REQUEST = 1; // 0x1
+ field public static final int DISCOVERY_ERROR_ABORTED = 1; // 0x1
+ field public static final int DISCOVERY_ERROR_NO_CONNECTIVITY = 2; // 0x2
+ field public static final int DISCOVERY_ERROR_UNKNOWN = 0; // 0x0
+ field public static final int DISCOVERY_FLAG_BACKGROUND = 1; // 0x1
+ field public static final int DISCOVERY_STATE_STARTED = 1; // 0x1
+ field public static final int DISCOVERY_STATE_STOPPED = 0; // 0x0
+ field public static final int ROUTE_FEATURE_LIVE_AUDIO = 1; // 0x1
+ field public static final int ROUTE_FEATURE_LIVE_VIDEO = 2; // 0x2
+ }
+
+ public static final class MediaRouter.ConnectionInfo {
+ method public android.media.AudioAttributes getAudioAttributes();
+ method public android.os.Bundle getExtras();
+ method public int getFeatures();
+ method public android.view.Display getPresentationDisplay();
+ method public android.os.IBinder getProtocolBinder(java.lang.String);
+ method public android.os.IBinder getProtocolBinder(int);
+ method public T getProtocolObject(java.lang.Class<T>);
+ method public java.util.List<java.lang.String> getProtocols();
+ method public android.media.routing.MediaRouter.RouteInfo getRoute();
+ method public android.media.VolumeProvider getVolumeProvider();
+ }
+
+ public static final class MediaRouter.ConnectionInfo.Builder {
+ ctor public MediaRouter.ConnectionInfo.Builder(android.media.routing.MediaRouter.RouteInfo);
+ method public android.media.routing.MediaRouter.ConnectionInfo build();
+ method public android.media.routing.MediaRouter.ConnectionInfo.Builder setAudioAttributes(android.media.AudioAttributes);
+ method public android.media.routing.MediaRouter.ConnectionInfo.Builder setExtras(android.os.Bundle);
+ method public android.media.routing.MediaRouter.ConnectionInfo.Builder setPresentationDisplay(android.view.Display);
+ method public android.media.routing.MediaRouter.ConnectionInfo.Builder setProtocolBinder(java.lang.String, android.os.IBinder);
+ method public android.media.routing.MediaRouter.ConnectionInfo.Builder setProtocolStub(java.lang.Class<?>, android.os.IInterface);
+ method public android.media.routing.MediaRouter.ConnectionInfo.Builder setVolumeProvider(android.media.VolumeProvider);
+ }
+
+ public static final class MediaRouter.ConnectionRequest {
+ method public android.os.Bundle getExtras();
+ method public int getFlags();
+ method public android.media.routing.MediaRouter.RouteInfo getRoute();
+ method public void setExtras(android.os.Bundle);
+ method public void setFlags(int);
+ method public void setRoute(android.media.routing.MediaRouter.RouteInfo);
+ }
+
+ public static final class MediaRouter.Delegate {
+ ctor public MediaRouter.Delegate();
+ method public void addStateCallback(android.media.routing.MediaRouter.StateCallback, android.os.Handler);
+ method public void connect(android.media.routing.MediaRouter.DestinationInfo, int);
+ method public void disconnect(int);
+ method public int getConnectionState();
+ method public java.util.List<android.media.routing.MediaRouter.DestinationInfo> getDiscoveredDestinations();
+ method public int getDiscoveryState();
+ method public android.media.routing.MediaRouter.DestinationInfo getSelectedDestination();
+ method public boolean isReleased();
+ method public void removeStateCallback(android.media.routing.MediaRouter.StateCallback);
+ method public void startDiscovery(int);
+ method public void stopDiscovery();
+ }
+
+ public static final class MediaRouter.DestinationInfo {
+ method public java.lang.CharSequence getDescription();
+ method public android.os.Bundle getExtras();
+ method public int getIconResourceId();
+ method public java.lang.String getId();
+ method public java.lang.CharSequence getName();
+ method public android.media.routing.MediaRouter.ServiceMetadata getServiceMetadata();
+ method public android.graphics.drawable.Drawable loadIcon(android.content.pm.PackageManager);
+ }
+
+ public static final class MediaRouter.DestinationInfo.Builder {
+ ctor public MediaRouter.DestinationInfo.Builder(java.lang.String, android.media.routing.MediaRouter.ServiceMetadata, java.lang.CharSequence);
+ method public android.media.routing.MediaRouter.DestinationInfo build();
+ method public android.media.routing.MediaRouter.DestinationInfo.Builder setDescription(java.lang.CharSequence);
+ method public android.media.routing.MediaRouter.DestinationInfo.Builder setExtras(android.os.Bundle);
+ method public android.media.routing.MediaRouter.DestinationInfo.Builder setIconResourceId(int);
+ }
+
+ public static final class MediaRouter.DiscoveryRequest {
+ method public int getFlags();
+ method public java.util.List<android.media.routing.MediaRouteSelector> getSelectors();
+ method public void setFlags(int);
+ method public void setSelectors(java.util.List<android.media.routing.MediaRouteSelector>);
+ }
+
+ public static final class MediaRouter.RouteInfo {
+ method public android.media.routing.MediaRouter.DestinationInfo getDestination();
+ method public android.os.Bundle getExtras();
+ method public int getFeatures();
+ method public java.lang.String getId();
+ method public java.util.List<java.lang.String> getProtocols();
+ method public android.media.routing.MediaRouteSelector getSelector();
+ }
+
+ public static final class MediaRouter.RouteInfo.Builder {
+ ctor public MediaRouter.RouteInfo.Builder(java.lang.String, android.media.routing.MediaRouter.DestinationInfo, android.media.routing.MediaRouteSelector);
+ method public android.media.routing.MediaRouter.RouteInfo.Builder addProtocol(java.lang.Class<T>);
+ method public android.media.routing.MediaRouter.RouteInfo.Builder addProtocol(java.lang.String);
+ method public android.media.routing.MediaRouter.RouteInfo build();
+ method public android.media.routing.MediaRouter.RouteInfo.Builder setExtras(android.os.Bundle);
+ method public android.media.routing.MediaRouter.RouteInfo.Builder setFeatures(int);
+ }
+
+ public static abstract class MediaRouter.RoutingCallback extends android.media.routing.MediaRouter.StateCallback {
+ ctor public MediaRouter.RoutingCallback();
+ method public boolean onPrepareConnectionRequest(android.media.routing.MediaRouter.ConnectionRequest, android.media.routing.MediaRouter.DestinationInfo, java.util.List<android.media.routing.MediaRouter.RouteInfo>);
+ method public boolean onPrepareDiscoveryRequest(android.media.routing.MediaRouter.DiscoveryRequest, java.util.List<android.media.routing.MediaRouteSelector>);
+ }
+
+ public static final class MediaRouter.ServiceMetadata {
+ method public android.content.ComponentName getComponentName();
+ method public android.graphics.drawable.Drawable getIcon(android.content.pm.PackageManager);
+ method public java.lang.CharSequence getLabel(android.content.pm.PackageManager);
+ method public java.lang.String getPackageName();
+ method public android.content.pm.ServiceInfo getService();
+ }
+
+ public static abstract class MediaRouter.StateCallback {
+ ctor public MediaRouter.StateCallback();
+ method public void onConnected();
+ method public void onConnecting();
+ method public void onConnectionFailed(int, java.lang.CharSequence, android.os.Bundle);
+ method public void onConnectionStateChanged(int);
+ method public void onDestinationFound(android.media.routing.MediaRouter.DestinationInfo);
+ method public void onDestinationLost(android.media.routing.MediaRouter.DestinationInfo);
+ method public void onDisconnected();
+ method public void onDiscoveryFailed(int, java.lang.CharSequence, android.os.Bundle);
+ method public void onDiscoveryStarted();
+ method public void onDiscoveryStateChanged(int);
+ method public void onDiscoveryStopped();
+ method public void onReleased();
+ method public void onSelectedDestinationChanged(android.media.routing.MediaRouter.DestinationInfo);
+ }
+
+}
+
package android.media.session {
public final class MediaController {
ctor public MediaController(android.content.Context, android.media.session.MediaSession.Token);
method public void adjustVolume(int, int);
+ method public android.media.routing.MediaRouter.Delegate createMediaRouterDelegate();
method public boolean dispatchMediaButtonEvent(android.view.KeyEvent);
method public android.os.Bundle getExtras();
method public long getFlags();
@@ -16309,6 +16552,7 @@
method public void setExtras(android.os.Bundle);
method public void setFlags(int);
method public void setMediaButtonReceiver(android.app.PendingIntent);
+ method public void setMediaRouter(android.media.routing.MediaRouter);
method public void setMetadata(android.media.MediaMetadata);
method public void setPlaybackState(android.media.session.PlaybackState);
method public void setPlaybackToLocal(android.media.AudioAttributes);
@@ -21618,7 +21862,7 @@
field public static final int TRACE_COUNT_ALLOCS = 1; // 0x1
}
- public static class Debug.InstructionCount {
+ public static deprecated class Debug.InstructionCount {
ctor public Debug.InstructionCount();
method public boolean collect();
method public int globalMethodInvocations();
@@ -28420,6 +28664,7 @@
method public void downloadMultimediaMessage(android.content.Context, java.lang.String, android.net.Uri, android.os.Bundle, android.app.PendingIntent);
method public android.os.Bundle getCarrierConfigValues();
method public static android.telephony.SmsManager getDefault();
+ method public static int getDefaultSmsSubscriptionId();
method public static android.telephony.SmsManager getSmsManagerForSubscriber(int);
method public int getSubId();
method public void injectSmsPdu(byte[], java.lang.String, android.app.PendingIntent);
@@ -28538,7 +28783,7 @@
field public byte[] encodedScAddress;
}
- public class SubInfoRecord implements android.os.Parcelable {
+ public class SubscriptionInfo implements android.os.Parcelable {
method public android.graphics.Bitmap createIconBitmap(android.content.Context);
method public int describeContents();
method public int getDataRoaming();
@@ -28552,25 +28797,23 @@
method public int getSimSlotIndex();
method public int getSubscriptionId();
method public void writeToParcel(android.os.Parcel, int);
- field public static final android.os.Parcelable.Creator<android.telephony.SubInfoRecord> CREATOR;
+ field public static final android.os.Parcelable.Creator<android.telephony.SubscriptionInfo> CREATOR;
+ }
+
+ public class SubscriptionListener {
+ ctor public SubscriptionListener();
+ ctor public SubscriptionListener(android.os.Looper);
+ method public void onSubscriptionInfoChanged();
+ field public static final int LISTEN_SUBSCRIPTION_INFO_LIST_CHANGED = 1; // 0x1
}
public class SubscriptionManager implements android.provider.BaseColumns {
- method public static java.util.List<android.telephony.SubInfoRecord> getActiveSubInfoList();
- method public static int getDefaultSmsSubId();
- method public static int getSlotId(int);
- method public static android.telephony.SubInfoRecord getSubInfoForSubscriber(int);
- method public static java.util.List<android.telephony.SubInfoRecord> getSubInfoUsingSlotId(int);
- method public static boolean isValidSubId(int);
- field public static final int ASK_USER_SUB_ID = -1001; // 0xfffffc17
- field public static final int DEFAULT_PHONE_ID = 2147483647; // 0x7fffffff
- field public static final int DEFAULT_SUB_ID = 2147483647; // 0x7fffffff
- field public static final int INVALID_PHONE_ID = -1000; // 0xfffffc18
- field public static final int INVALID_SLOT_ID = -1000; // 0xfffffc18
+ method public static java.util.List<android.telephony.SubscriptionInfo> getActiveSubscriptionInfoList();
+ method public static android.telephony.SubscriptionInfo getSubscriptionInfoForSubscriber(int);
+ method public static java.util.List<android.telephony.SubscriptionInfo> getSubscriptionInfoUsingSlotId(int);
+ method public static void register(android.content.Context, android.telephony.SubscriptionListener, int);
+ method public static void unregister(android.content.Context, android.telephony.SubscriptionListener);
field public static final int INVALID_SUB_ID = -1000; // 0xfffffc18
- field public static final java.lang.String MCC = "mcc";
- field public static final java.lang.String MNC = "mnc";
- field public static final int SIM_NOT_INSERTED = -1; // 0xffffffff
}
public class TelephonyManager {
@@ -33083,6 +33326,7 @@
method public int describeContents();
method public boolean isValid();
method public android.graphics.Canvas lockCanvas(android.graphics.Rect) throws java.lang.IllegalArgumentException, android.view.Surface.OutOfResourcesException;
+ method public android.graphics.Canvas lockHardwareCanvas();
method public void readFromParcel(android.os.Parcel);
method public void release();
method public deprecated void unlockCanvas(android.graphics.Canvas);
diff --git a/cmds/am/src/com/android/commands/am/Am.java b/cmds/am/src/com/android/commands/am/Am.java
index bc57030..0cad17d 100644
--- a/cmds/am/src/com/android/commands/am/Am.java
+++ b/cmds/am/src/com/android/commands/am/Am.java
@@ -127,6 +127,7 @@
" am screen-compat [on|off] <PACKAGE>\n" +
" am to-uri [INTENT]\n" +
" am to-intent-uri [INTENT]\n" +
+ " am to-app-uri [INTENT]\n" +
" am switch-user <USER_ID>\n" +
" am start-user <USER_ID>\n" +
" am stop-user <USER_ID>\n" +
@@ -229,6 +230,8 @@
"\n" +
"am to-intent-uri: print the given Intent specification as an intent: URI.\n" +
"\n" +
+ "am to-app-uri: print the given Intent specification as an android-app: URI.\n" +
+ "\n" +
"am switch-user: switch to put USER_ID in the foreground, starting\n" +
" execution of that user if it is currently stopped.\n" +
"\n" +
@@ -270,7 +273,7 @@
" [--efa <EXTRA_KEY> <EXTRA_FLOAT_VALUE>[,<EXTRA_FLOAT_VALUE...]]\n" +
" [--esa <EXTRA_KEY> <EXTRA_STRING_VALUE>[,<EXTRA_STRING_VALUE...]]\n" +
" (to embed a comma into a string escape it using \"\\,\")\n" +
- " [-n <COMPONENT>] [-f <FLAGS>]\n" +
+ " [-n <COMPONENT>] [-p <PACKAGE>] [-f <FLAGS>]\n" +
" [--grant-read-uri-permission] [--grant-write-uri-permission]\n" +
" [--grant-persistable-uri-permission] [--grant-prefix-uri-permission]\n" +
" [--debug-log-resolution] [--exclude-stopped-packages]\n" +
@@ -337,9 +340,11 @@
} else if (op.equals("screen-compat")) {
runScreenCompat();
} else if (op.equals("to-uri")) {
- runToUri(false);
+ runToUri(0);
} else if (op.equals("to-intent-uri")) {
- runToUri(true);
+ runToUri(Intent.URI_INTENT_SCHEME);
+ } else if (op.equals("to-app-uri")) {
+ runToUri(Intent.URI_ANDROID_APP_SCHEME);
} else if (op.equals("switch-user")) {
runSwitchUser();
} else if (op.equals("start-user")) {
@@ -502,6 +507,12 @@
if (intent == baseIntent) {
hasIntentInfo = true;
}
+ } else if (opt.equals("-p")) {
+ String str = nextArgRequired();
+ intent.setPackage(str);
+ if (intent == baseIntent) {
+ hasIntentInfo = true;
+ }
} else if (opt.equals("-f")) {
String str = nextArgRequired();
intent.setFlags(Integer.decode(str).intValue());
@@ -607,7 +618,8 @@
} else if (arg.indexOf(':') >= 0) {
// The argument is a URI. Fully parse it, and use that result
// to fill in any data not specified so far.
- baseIntent = Intent.parseUri(arg, Intent.URI_INTENT_SCHEME);
+ baseIntent = Intent.parseUri(arg, Intent.URI_INTENT_SCHEME
+ | Intent.URI_ANDROID_APP_SCHEME);
} else if (arg.indexOf('/') >= 0) {
// The argument is a component name. Build an Intent to launch
// it.
@@ -1549,9 +1561,9 @@
} while (packageName != null);
}
- private void runToUri(boolean intentScheme) throws Exception {
+ private void runToUri(int flags) throws Exception {
Intent intent = makeIntent(UserHandle.USER_CURRENT);
- System.out.println(intent.toUri(intentScheme ? Intent.URI_INTENT_SCHEME : 0));
+ System.out.println(intent.toUri(flags));
}
private class IntentReceiver extends IIntentReceiver.Stub {
diff --git a/cmds/app_process/Android.mk b/cmds/app_process/Android.mk
index 1ca14a6..dd5e0ea 100644
--- a/cmds/app_process/Android.mk
+++ b/cmds/app_process/Android.mk
@@ -2,28 +2,28 @@
include $(CLEAR_VARS)
-# TODO: Trying to link libsigchain as a static library prevents
-# static linker from exporting necessary symbols. So as a workaround
-# we use sigchain.o
LOCAL_SRC_FILES:= \
- app_main.cpp \
- sigchain_proxy.cpp
+ app_main.cpp
LOCAL_LDFLAGS := -Wl,--version-script,art/sigchainlib/version-script.txt -Wl,--export-dynamic
-LOCAL_CPPFLAGS := -std=c++11 -Iart
LOCAL_SHARED_LIBRARIES := \
- libdl \
- libcutils \
- libutils \
- liblog \
- libbinder \
- libandroid_runtime
+ libdl \
+ libcutils \
+ libutils \
+ liblog \
+ libbinder \
+ libandroid_runtime
+
+LOCAL_WHOLE_STATIC_LIBRARIES := libsigchain
LOCAL_MODULE:= app_process
LOCAL_MULTILIB := both
LOCAL_MODULE_STEM_32 := app_process32
LOCAL_MODULE_STEM_64 := app_process64
+
+LOCAL_CFLAGS += -Wall -Werror -Wunused -Wunreachable-code
+
include $(BUILD_EXECUTABLE)
# Create a symlink from app_process to app_process32 or 64
@@ -36,20 +36,20 @@
include $(CLEAR_VARS)
-# see comment above (~l5)
LOCAL_SRC_FILES:= \
- app_main.cpp \
- sigchain_proxy.cpp
+ app_main.cpp
LOCAL_SHARED_LIBRARIES := \
- libcutils \
- libutils \
- liblog \
- libbinder \
- libandroid_runtime
+ libcutils \
+ libutils \
+ liblog \
+ libbinder \
+ libandroid_runtime
+
+LOCAL_WHOLE_STATIC_LIBRARIES := libsigchain
LOCAL_LDFLAGS := -ldl -Wl,--version-script,art/sigchainlib/version-script.txt -Wl,--export-dynamic
-LOCAL_CPPFLAGS := -std=c++11 -Iart
+LOCAL_CPPFLAGS := -std=c++11
LOCAL_MODULE := app_process__asan
LOCAL_MODULE_TAGS := eng
@@ -57,6 +57,8 @@
LOCAL_MODULE_STEM := app_process
LOCAL_ADDRESS_SANITIZER := true
+LOCAL_CFLAGS += -Wall -Werror -Wunused -Wunreachable-code
+
include $(BUILD_EXECUTABLE)
endif # ifeq($(TARGET_ARCH),arm)
diff --git a/cmds/app_process/app_main.cpp b/cmds/app_process/app_main.cpp
index 1bb28c3..fbdbb25 100644
--- a/cmds/app_process/app_main.cpp
+++ b/cmds/app_process/app_main.cpp
@@ -24,7 +24,7 @@
namespace android {
-void app_usage()
+static void app_usage()
{
fprintf(stderr,
"Usage: app_process [java-options] cmd-dir start-class-name [options]\n");
diff --git a/cmds/backup/Android.mk b/cmds/backup/Android.mk
index 42e5133..8e1508c 100644
--- a/cmds/backup/Android.mk
+++ b/cmds/backup/Android.mk
@@ -12,4 +12,6 @@
LOCAL_MODULE_PATH := $(TARGET_OUT_OPTIONAL_EXECUTABLES)
LOCAL_MODULE_TAGS := optional
+LOCAL_CFLAGS += -Wall -Werror -Wunused -Wunreachable-code
+
include $(BUILD_EXECUTABLE)
diff --git a/cmds/backup/backup.cpp b/cmds/backup/backup.cpp
index ea1888b..8d9b528 100644
--- a/cmds/backup/backup.cpp
+++ b/cmds/backup/backup.cpp
@@ -25,8 +25,7 @@
#include <unistd.h>
-int
-usage(int argc, const char** argv)
+static int usage(int /* argc */, const char** argv)
{
const char* p = argv[0];
@@ -44,15 +43,13 @@
return 1;
}
-int
-perform_full_backup()
+static int perform_full_backup()
{
printf("this would have written all of your data to stdout\n");
return 0;
}
-int
-perform_list(const char* filename)
+static int perform_list(const char* filename)
{
int err;
int fd;
@@ -78,7 +75,7 @@
size_t dataSize;
err = reader.ReadEntityHeader(&key, &dataSize);
if (err == 0) {
- printf(" entity: %s (%d bytes)\n", key.string(), dataSize);
+ printf(" entity: %s (%zu bytes)\n", key.string(), dataSize);
} else {
printf(" Error reading entity header\n");
}
@@ -95,14 +92,13 @@
return 0;
}
-int perform_print(const char* entityname, const char* filename)
+static int perform_print(const char* entityname, const char* filename)
{
printf("perform_print(%s, %s);", entityname, filename);
return 0;
}
-int
-main(int argc, const char** argv)
+int main(int argc, const char** argv)
{
if (argc <= 1) {
return perform_full_backup();
diff --git a/cmds/bootanimation/Android.mk b/cmds/bootanimation/Android.mk
index d6ecbe3..2ee586f 100644
--- a/cmds/bootanimation/Android.mk
+++ b/cmds/bootanimation/Android.mk
@@ -2,22 +2,24 @@
include $(CLEAR_VARS)
LOCAL_SRC_FILES:= \
- bootanimation_main.cpp \
- AudioPlayer.cpp \
- BootAnimation.cpp
+ bootanimation_main.cpp \
+ AudioPlayer.cpp \
+ BootAnimation.cpp
LOCAL_CFLAGS += -DGL_GLEXT_PROTOTYPES -DEGL_EGLEXT_PROTOTYPES
+LOCAL_CFLAGS += -Wall -Werror -Wunused -Wunreachable-code
+
LOCAL_C_INCLUDES += external/tinyalsa/include
LOCAL_SHARED_LIBRARIES := \
- libcutils \
- liblog \
- libandroidfw \
- libutils \
- libbinder \
+ libcutils \
+ liblog \
+ libandroidfw \
+ libutils \
+ libbinder \
libui \
- libskia \
+ libskia \
libEGL \
libGLESv1_CM \
libgui \
diff --git a/cmds/bootanimation/AudioPlayer.cpp b/cmds/bootanimation/AudioPlayer.cpp
index 471b77f..459190f 100644
--- a/cmds/bootanimation/AudioPlayer.cpp
+++ b/cmds/bootanimation/AudioPlayer.cpp
@@ -207,7 +207,6 @@
struct pcm *pcm = NULL;
bool moreChunks = true;
const struct chunk_fmt* chunkFmt = NULL;
- void* buffer = NULL;
int bufferSize;
const uint8_t* wavData;
size_t wavLength;
diff --git a/cmds/bootanimation/BootAnimation.cpp b/cmds/bootanimation/BootAnimation.cpp
index b2474f2..1d4de22 100644
--- a/cmds/bootanimation/BootAnimation.cpp
+++ b/cmds/bootanimation/BootAnimation.cpp
@@ -23,6 +23,7 @@
#include <fcntl.h>
#include <utils/misc.h>
#include <signal.h>
+#include <time.h>
#include <cutils/properties.h>
@@ -41,9 +42,13 @@
#include <gui/Surface.h>
#include <gui/SurfaceComposerClient.h>
+// TODO: Fix Skia.
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wunused-parameter"
#include <SkBitmap.h>
#include <SkStream.h>
#include <SkImageDecoder.h>
+#pragma GCC diagnostic pop
#include <GLES/gl.h>
#include <GLES/glext.h>
@@ -57,10 +62,6 @@
#define SYSTEM_ENCRYPTED_BOOTANIMATION_FILE "/system/media/bootanimation-encrypted.zip"
#define EXIT_PROP_NAME "service.bootanim.exit"
-extern "C" int clock_nanosleep(clockid_t clock_id, int flags,
- const struct timespec *request,
- struct timespec *remain);
-
namespace android {
static const int ANIM_ENTRY_NAME_MAX = 256;
@@ -108,7 +109,7 @@
status_t BootAnimation::initTexture(Texture* texture, AssetManager& assets,
const char* name) {
Asset* asset = assets.open(name, Asset::ACCESS_BUFFER);
- if (!asset)
+ if (asset == NULL)
return NO_INIT;
SkBitmap bitmap;
SkImageDecoder::DecodeMemory(asset->getBuffer(false), asset->getLength(),
@@ -167,7 +168,7 @@
SkBitmap bitmap;
SkMemoryStream stream(frame.map->getDataPtr(), frame.map->getDataLength());
SkImageDecoder* codec = SkImageDecoder::Factory(&stream);
- if (codec) {
+ if (codec != NULL) {
codec->setDitherImage(false);
codec->decode(&stream, &bitmap,
kN32_SkColorType,
@@ -255,7 +256,7 @@
EGL_DEPTH_SIZE, 0,
EGL_NONE
};
- EGLint w, h, dummy;
+ EGLint w, h;
EGLint numConfigs;
EGLConfig config;
EGLSurface surface;
@@ -473,7 +474,7 @@
// Parse the description file
for (;;) {
const char* endl = strstr(s, "\n");
- if (!endl) break;
+ if (endl == NULL) break;
String8 line(s, endl - s);
const char* l = line.string();
int fps, width, height, count, pause;
@@ -575,7 +576,6 @@
const int xc = (mWidth - animation.width) / 2;
const int yc = ((mHeight - animation.height) / 2);
- nsecs_t lastFrame = systemTime();
nsecs_t frameDuration = s2ns(1) / animation.fps;
Region clearReg(Rect(mWidth, mHeight));
@@ -623,9 +623,9 @@
Region::const_iterator tail(clearReg.end());
glEnable(GL_SCISSOR_TEST);
while (head != tail) {
- const Rect& r(*head++);
- glScissor(r.left, mHeight - r.bottom,
- r.width(), r.height());
+ const Rect& r2(*head++);
+ glScissor(r2.left, mHeight - r2.bottom,
+ r2.width(), r2.height());
glClear(GL_COLOR_BUFFER_BIT);
}
glDisable(GL_SCISSOR_TEST);
diff --git a/cmds/bootanimation/bootanimation_main.cpp b/cmds/bootanimation/bootanimation_main.cpp
index 417e138..6550d22 100644
--- a/cmds/bootanimation/bootanimation_main.cpp
+++ b/cmds/bootanimation/bootanimation_main.cpp
@@ -36,7 +36,7 @@
// ---------------------------------------------------------------------------
-int main(int argc, char** argv)
+int main()
{
#if defined(HAVE_PTHREADS)
setpriority(PRIO_PROCESS, 0, ANDROID_PRIORITY_DISPLAY);
diff --git a/cmds/idmap/Android.mk b/cmds/idmap/Android.mk
index ffa83f2..50ccb07 100644
--- a/cmds/idmap/Android.mk
+++ b/cmds/idmap/Android.mk
@@ -25,4 +25,6 @@
LOCAL_MODULE_TAGS := optional
+LOCAL_CFLAGS += -Wall -Werror -Wunused -Wunreachable-code
+
include $(BUILD_EXECUTABLE)
diff --git a/cmds/idmap/create.cpp b/cmds/idmap/create.cpp
index 593a197..7a501a4 100644
--- a/cmds/idmap/create.cpp
+++ b/cmds/idmap/create.cpp
@@ -22,7 +22,7 @@
if (entry == NULL) {
return -1;
}
- if (!zip->getEntryInfo(entry, NULL, NULL, NULL, NULL, NULL, (long*)crc)) {
+ if (!zip->getEntryInfo(entry, NULL, NULL, NULL, NULL, NULL, reinterpret_cast<long*>(crc))) {
return -1;
}
zip->releaseEntry(entry);
@@ -66,7 +66,7 @@
fprintf(stderr, "error: write: %s\n", strerror(errno));
return -1;
}
- bytesLeft -= w;
+ bytesLeft -= static_cast<size_t>(w);
}
return 0;
}
@@ -78,13 +78,13 @@
if (fstat(idmap_fd, &st) == -1) {
return true;
}
- if (st.st_size < N) {
+ if (st.st_size < static_cast<off_t>(N)) {
// file is empty or corrupt
return true;
}
char buf[N];
- ssize_t bytesLeft = N;
+ size_t bytesLeft = N;
if (lseek(idmap_fd, SEEK_SET, 0) < 0) {
return true;
}
@@ -93,7 +93,7 @@
if (r < 0) {
return true;
}
- bytesLeft -= r;
+ bytesLeft -= static_cast<size_t>(r);
if (bytesLeft == 0) {
break;
}
diff --git a/cmds/idmap/inspect.cpp b/cmds/idmap/inspect.cpp
index b9ac8a5..f6afc85 100644
--- a/cmds/idmap/inspect.cpp
+++ b/cmds/idmap/inspect.cpp
@@ -152,13 +152,13 @@
printe("failed to get resource name id=0x%08x\n", res_id);
return UNKNOWN_ERROR;
}
- if (package) {
+ if (package != NULL) {
*package = String8(String16(data.package, data.packageLen));
}
- if (type) {
+ if (type != NULL) {
*type = String8(String16(data.type, data.typeLen));
}
- if (name) {
+ if (name != NULL) {
*name = String8(String16(data.name, data.nameLen));
}
return NO_ERROR;
diff --git a/cmds/idmap/scan.cpp b/cmds/idmap/scan.cpp
index 1153f38..4f19a74 100644
--- a/cmds/idmap/scan.cpp
+++ b/cmds/idmap/scan.cpp
@@ -64,30 +64,6 @@
return String8(tmp);
}
- int mkdir_p(const String8& path, uid_t uid, gid_t gid)
- {
- static const mode_t mode =
- S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IWGRP | S_IXGRP | S_IROTH | S_IXOTH;
- struct stat st;
-
- if (stat(path.string(), &st) == 0) {
- return 0;
- }
- if (mkdir_p(path.getPathDir(), uid, gid) < 0) {
- return -1;
- }
- if (mkdir(path.string(), 0755) != 0) {
- return -1;
- }
- if (chown(path.string(), uid, gid) == -1) {
- return -1;
- }
- if (chmod(path.string(), mode) == -1) {
- return -1;
- }
- return 0;
- }
-
int parse_overlay_tag(const ResXMLTree& parser, const char *target_package_name)
{
const size_t N = parser.getAttributeCount();
@@ -98,7 +74,7 @@
String16 key(parser.getAttributeName(i, &len));
if (key == String16("targetPackage")) {
const uint16_t *p = parser.getAttributeStringValue(i, &len);
- if (p) {
+ if (p != NULL) {
target = String16(p, len);
}
} else if (key == String16("priority")) {
@@ -164,7 +140,7 @@
return -1;
}
FileMap *dataMap = zip->createEntryFileMap(entry);
- if (!dataMap) {
+ if (dataMap == NULL) {
ALOGW("%s: failed to create FileMap\n", __FUNCTION__);
return -1;
}
diff --git a/cmds/interrupter/Android.mk b/cmds/interrupter/Android.mk
index e324627..97a96bf 100644
--- a/cmds/interrupter/Android.mk
+++ b/cmds/interrupter/Android.mk
@@ -7,6 +7,7 @@
LOCAL_MODULE := interrupter
LOCAL_MODULE_TAGS := eng tests
LOCAL_LDFLAGS := -ldl
+LOCAL_CFLAGS := -Wall -Werror -Wunused -Wunreachable-code
include $(BUILD_SHARED_LIBRARY)
@@ -17,5 +18,6 @@
LOCAL_MODULE := interrupter
LOCAL_MODULE_TAGS := eng tests
LOCAL_LDFLAGS := -ldl
+LOCAL_CFLAGS := -Wall -Werror -Wunused -Wunreachable-code
-include $(BUILD_HOST_SHARED_LIBRARY)
\ No newline at end of file
+include $(BUILD_HOST_SHARED_LIBRARY)
diff --git a/cmds/screencap/Android.mk b/cmds/screencap/Android.mk
index 5c11b75..b0dc422 100644
--- a/cmds/screencap/Android.mk
+++ b/cmds/screencap/Android.mk
@@ -2,13 +2,13 @@
include $(CLEAR_VARS)
LOCAL_SRC_FILES:= \
- screencap.cpp
+ screencap.cpp
LOCAL_SHARED_LIBRARIES := \
- libcutils \
- libutils \
- libbinder \
- libskia \
+ libcutils \
+ libutils \
+ libbinder \
+ libskia \
libui \
libgui
@@ -16,4 +16,6 @@
LOCAL_MODULE_TAGS := optional
+LOCAL_CFLAGS += -Wall -Werror -Wunused -Wunreachable-code
+
include $(BUILD_EXECUTABLE)
diff --git a/cmds/screencap/screencap.cpp b/cmds/screencap/screencap.cpp
index 6b2a0e2..b0aee7b 100644
--- a/cmds/screencap/screencap.cpp
+++ b/cmds/screencap/screencap.cpp
@@ -18,6 +18,8 @@
#include <unistd.h>
#include <stdio.h>
#include <fcntl.h>
+#include <stdlib.h>
+#include <string.h>
#include <linux/fb.h>
#include <sys/ioctl.h>
@@ -30,10 +32,14 @@
#include <ui/PixelFormat.h>
+// TODO: Fix Skia.
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wunused-parameter"
#include <SkImageEncoder.h>
#include <SkBitmap.h>
#include <SkData.h>
#include <SkStream.h>
+#pragma GCC diagnostic pop
using namespace android;
@@ -86,6 +92,21 @@
return NO_ERROR;
}
+static status_t notifyMediaScanner(const char* fileName) {
+ String8 cmd("am broadcast -a android.intent.action.MEDIA_SCANNER_SCAN_FILE -d file://");
+ String8 fileUrl("\"");
+ fileUrl.append(fileName);
+ fileUrl.append("\"");
+ cmd.append(fileName);
+ cmd.append(" > /dev/null");
+ int result = system(cmd.string());
+ if (result < 0) {
+ fprintf(stderr, "Unable to broadcast intent for media scanner.\n");
+ return UNKNOWN_ERROR;
+ }
+ return NO_ERROR;
+}
+
int main(int argc, char** argv)
{
ProcessState::self()->startThreadPool();
@@ -112,10 +133,11 @@
argv += optind;
int fd = -1;
+ const char* fn = NULL;
if (argc == 0) {
fd = dup(STDOUT_FILENO);
} else if (argc == 1) {
- const char* fn = argv[0];
+ fn = argv[0];
fd = open(fn, O_WRONLY | O_CREAT | O_TRUNC, 0664);
if (fd == -1) {
fprintf(stderr, "Error opening file: %s (%s)\n", fn, strerror(errno));
@@ -135,7 +157,7 @@
void const* mapbase = MAP_FAILED;
ssize_t mapsize = -1;
- void const* base = 0;
+ void const* base = NULL;
uint32_t w, s, h, f;
size_t size = 0;
@@ -172,7 +194,7 @@
}
}
- if (base) {
+ if (base != NULL) {
if (png) {
const SkImageInfo info = SkImageInfo::Make(w, h, flinger2skia(f),
kPremul_SkAlphaType);
@@ -184,6 +206,9 @@
SkData* streamData = stream.copyToData();
write(fd, streamData->data(), streamData->size());
streamData->unref();
+ if (fn != NULL) {
+ notifyMediaScanner(fn);
+ }
} else {
write(fd, &w, 4);
write(fd, &h, 4);
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index 4b705dd..148527f 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -693,6 +693,7 @@
/*package*/ String mEmbeddedID;
private Application mApplication;
/*package*/ Intent mIntent;
+ /*package*/ String mReferrer;
private ComponentName mComponent;
/*package*/ ActivityInfo mActivityInfo;
/*package*/ ActivityThread mMainThread;
@@ -4448,6 +4449,39 @@
}
/**
+ * Return information about who launched this activity. If the launching Intent
+ * contains an {@link android.content.Intent#EXTRA_REFERRER Intent.EXTRA_REFERRER},
+ * that will be returned as-is; otherwise, if known, an
+ * {@link Intent#URI_ANDROID_APP_SCHEME android-app:} referrer URI containing the
+ * package name that started the Intent will be returned. This may return null if no
+ * referrer can be identified -- it is neither explicitly specified, nor is it known which
+ * application package was involved.
+ *
+ * <p>If called while inside the handling of {@link #onNewIntent}, this function will
+ * return the referrer that submitted that new intent to the activity. Otherwise, it
+ * always returns the referrer of the original Intent.</p>
+ *
+ * <p>Note that this is <em>not</em> a security feature -- you can not trust the
+ * referrer information, applications can spoof it.</p>
+ */
+ @Nullable
+ public Uri getReferrer() {
+ Intent intent = getIntent();
+ Uri referrer = intent.getParcelableExtra(Intent.EXTRA_REFERRER);
+ if (referrer != null) {
+ return referrer;
+ }
+ String referrerName = intent.getStringExtra(Intent.EXTRA_REFERRER_NAME);
+ if (referrerName != null) {
+ return Uri.parse(referrerName);
+ }
+ if (mReferrer != null) {
+ return new Uri.Builder().scheme("android-app").authority(mReferrer).build();
+ }
+ return null;
+ }
+
+ /**
* Return the name of the package that invoked this activity. This is who
* the data in {@link #setResult setResult()} will be sent to. You can
* use this information to validate that the recipient is allowed to
@@ -5868,7 +5902,7 @@
Application application, Intent intent, ActivityInfo info,
CharSequence title, Activity parent, String id,
NonConfigurationInstances lastNonConfigurationInstances,
- Configuration config, IVoiceInteractor voiceInteractor) {
+ Configuration config, String referrer, IVoiceInteractor voiceInteractor) {
attachBaseContext(context);
mFragments.attachActivity(this, mContainer, null);
@@ -5891,6 +5925,7 @@
mIdent = ident;
mApplication = application;
mIntent = intent;
+ mReferrer = referrer;
mComponent = intent.getComponent();
mActivityInfo = info;
mTitle = title;
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index cf6c049..de8e1d6 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -94,6 +94,7 @@
import android.security.AndroidKeyStoreProvider;
import com.android.internal.app.IVoiceInteractor;
+import com.android.internal.content.ReferrerIntent;
import com.android.internal.os.BinderInternal;
import com.android.internal.os.RuntimeInit;
import com.android.internal.os.SamplingProfilerIntegration;
@@ -268,6 +269,7 @@
IBinder token;
int ident;
Intent intent;
+ String referrer;
IVoiceInteractor voiceInteractor;
Bundle state;
PersistableBundle persistentState;
@@ -290,7 +292,7 @@
LoadedApk packageInfo;
List<ResultInfo> pendingResults;
- List<Intent> pendingIntents;
+ List<ReferrerIntent> pendingIntents;
boolean startsNotResumed;
boolean isForward;
@@ -348,7 +350,7 @@
}
static final class NewIntentData {
- List<Intent> intents;
+ List<ReferrerIntent> intents;
IBinder token;
public String toString() {
return "NewIntentData{intents=" + intents + " token=" + token + "}";
@@ -605,9 +607,9 @@
// activity itself back to the activity manager. (matters more with ipc)
public final void scheduleLaunchActivity(Intent intent, IBinder token, int ident,
ActivityInfo info, Configuration curConfig, CompatibilityInfo compatInfo,
- IVoiceInteractor voiceInteractor, int procState, Bundle state,
+ String referrer, IVoiceInteractor voiceInteractor, int procState, Bundle state,
PersistableBundle persistentState, List<ResultInfo> pendingResults,
- List<Intent> pendingNewIntents, boolean notResumed, boolean isForward,
+ List<ReferrerIntent> pendingNewIntents, boolean notResumed, boolean isForward,
ProfilerInfo profilerInfo) {
updateProcessState(procState, false);
@@ -617,6 +619,7 @@
r.token = token;
r.ident = ident;
r.intent = intent;
+ r.referrer = referrer;
r.voiceInteractor = voiceInteractor;
r.activityInfo = info;
r.compatInfo = compatInfo;
@@ -637,13 +640,13 @@
}
public final void scheduleRelaunchActivity(IBinder token,
- List<ResultInfo> pendingResults, List<Intent> pendingNewIntents,
+ List<ResultInfo> pendingResults, List<ReferrerIntent> pendingNewIntents,
int configChanges, boolean notResumed, Configuration config) {
requestRelaunchActivity(token, pendingResults, pendingNewIntents,
configChanges, notResumed, config, true);
}
- public final void scheduleNewIntent(List<Intent> intents, IBinder token) {
+ public final void scheduleNewIntent(List<ReferrerIntent> intents, IBinder token) {
NewIntentData data = new NewIntentData();
data.intents = intents;
data.token = token;
@@ -1945,7 +1948,7 @@
if (dumpFullInfo) {
printRow(pw, HEAP_FULL_COLUMN, "", "Pss", "Pss", "Shared", "Private",
"Shared", "Private", "Swapped", "Heap", "Heap", "Heap");
- printRow(pw, HEAP_FULL_COLUMN, "", "Total", "Clean", "Dirty", "",
+ printRow(pw, HEAP_FULL_COLUMN, "", "Total", "Clean", "Dirty", "Dirty",
"Clean", "Clean", "Dirty", "Size", "Alloc", "Free");
printRow(pw, HEAP_FULL_COLUMN, "", "------", "------", "------", "------",
"------", "------", "------", "------", "------", "------");
@@ -2234,7 +2237,7 @@
activity.attach(appContext, this, getInstrumentation(), r.token,
r.ident, app, r.intent, r.activityInfo, title, r.parent,
r.embeddedID, r.lastNonConfigurationInstances, config,
- r.voiceInteractor);
+ r.referrer, r.voiceInteractor);
if (customIntent != null) {
activity.mIntent = customIntent;
@@ -2421,8 +2424,7 @@
}
}
- private void deliverNewIntents(ActivityClientRecord r,
- List<Intent> intents) {
+ private void deliverNewIntents(ActivityClientRecord r, List<ReferrerIntent> intents) {
final int N = intents.size();
for (int i=0; i<N; i++) {
Intent intent = intents.get(i);
@@ -2433,8 +2435,7 @@
}
}
- public final void performNewIntents(IBinder token,
- List<Intent> intents) {
+ public final void performNewIntents(IBinder token, List<ReferrerIntent> intents) {
ActivityClientRecord r = mActivities.get(token);
if (r != null) {
final boolean resumed = !r.paused;
@@ -3752,7 +3753,7 @@
}
public final void requestRelaunchActivity(IBinder token,
- List<ResultInfo> pendingResults, List<Intent> pendingNewIntents,
+ List<ResultInfo> pendingResults, List<ReferrerIntent> pendingNewIntents,
int configChanges, boolean notResumed, Configuration config,
boolean fromServer) {
ActivityClientRecord target = null;
diff --git a/core/java/android/app/ApplicationThreadNative.java b/core/java/android/app/ApplicationThreadNative.java
index 0123e16..d1b77b9 100644
--- a/core/java/android/app/ApplicationThreadNative.java
+++ b/core/java/android/app/ApplicationThreadNative.java
@@ -36,6 +36,7 @@
import android.os.Parcel;
import android.os.ParcelFileDescriptor;
import com.android.internal.app.IVoiceInteractor;
+import com.android.internal.content.ReferrerIntent;
import java.io.FileDescriptor;
import java.io.IOException;
@@ -140,19 +141,21 @@
ActivityInfo info = ActivityInfo.CREATOR.createFromParcel(data);
Configuration curConfig = Configuration.CREATOR.createFromParcel(data);
CompatibilityInfo compatInfo = CompatibilityInfo.CREATOR.createFromParcel(data);
+ String referrer = data.readString();
IVoiceInteractor voiceInteractor = IVoiceInteractor.Stub.asInterface(
data.readStrongBinder());
int procState = data.readInt();
Bundle state = data.readBundle();
PersistableBundle persistentState = data.readPersistableBundle();
List<ResultInfo> ri = data.createTypedArrayList(ResultInfo.CREATOR);
- List<Intent> pi = data.createTypedArrayList(Intent.CREATOR);
+ List<ReferrerIntent> pi = data.createTypedArrayList(ReferrerIntent.CREATOR);
boolean notResumed = data.readInt() != 0;
boolean isForward = data.readInt() != 0;
ProfilerInfo profilerInfo = data.readInt() != 0
? ProfilerInfo.CREATOR.createFromParcel(data) : null;
- scheduleLaunchActivity(intent, b, ident, info, curConfig, compatInfo, voiceInteractor,
- procState, state, persistentState, ri, pi, notResumed, isForward, profilerInfo);
+ scheduleLaunchActivity(intent, b, ident, info, curConfig, compatInfo, referrer,
+ voiceInteractor, procState, state, persistentState, ri, pi,
+ notResumed, isForward, profilerInfo);
return true;
}
@@ -161,7 +164,7 @@
data.enforceInterface(IApplicationThread.descriptor);
IBinder b = data.readStrongBinder();
List<ResultInfo> ri = data.createTypedArrayList(ResultInfo.CREATOR);
- List<Intent> pi = data.createTypedArrayList(Intent.CREATOR);
+ List<ReferrerIntent> pi = data.createTypedArrayList(ReferrerIntent.CREATOR);
int configChanges = data.readInt();
boolean notResumed = data.readInt() != 0;
Configuration config = null;
@@ -175,7 +178,7 @@
case SCHEDULE_NEW_INTENT_TRANSACTION:
{
data.enforceInterface(IApplicationThread.descriptor);
- List<Intent> pi = data.createTypedArrayList(Intent.CREATOR);
+ List<ReferrerIntent> pi = data.createTypedArrayList(ReferrerIntent.CREATOR);
IBinder b = data.readStrongBinder();
scheduleNewIntent(pi, b);
return true;
@@ -764,9 +767,9 @@
public final void scheduleLaunchActivity(Intent intent, IBinder token, int ident,
ActivityInfo info, Configuration curConfig, CompatibilityInfo compatInfo,
- IVoiceInteractor voiceInteractor, int procState, Bundle state,
+ String referrer, IVoiceInteractor voiceInteractor, int procState, Bundle state,
PersistableBundle persistentState, List<ResultInfo> pendingResults,
- List<Intent> pendingNewIntents, boolean notResumed, boolean isForward,
+ List<ReferrerIntent> pendingNewIntents, boolean notResumed, boolean isForward,
ProfilerInfo profilerInfo) throws RemoteException {
Parcel data = Parcel.obtain();
data.writeInterfaceToken(IApplicationThread.descriptor);
@@ -776,6 +779,7 @@
info.writeToParcel(data, 0);
curConfig.writeToParcel(data, 0);
compatInfo.writeToParcel(data, 0);
+ data.writeString(referrer);
data.writeStrongBinder(voiceInteractor != null ? voiceInteractor.asBinder() : null);
data.writeInt(procState);
data.writeBundle(state);
@@ -796,7 +800,7 @@
}
public final void scheduleRelaunchActivity(IBinder token,
- List<ResultInfo> pendingResults, List<Intent> pendingNewIntents,
+ List<ResultInfo> pendingResults, List<ReferrerIntent> pendingNewIntents,
int configChanges, boolean notResumed, Configuration config)
throws RemoteException {
Parcel data = Parcel.obtain();
@@ -817,7 +821,7 @@
data.recycle();
}
- public void scheduleNewIntent(List<Intent> intents, IBinder token)
+ public void scheduleNewIntent(List<ReferrerIntent> intents, IBinder token)
throws RemoteException {
Parcel data = Parcel.obtain();
data.writeInterfaceToken(IApplicationThread.descriptor);
diff --git a/core/java/android/app/BackStackRecord.java b/core/java/android/app/BackStackRecord.java
index 0092ee7..2784d44 100644
--- a/core/java/android/app/BackStackRecord.java
+++ b/core/java/android/app/BackStackRecord.java
@@ -38,6 +38,7 @@
import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.util.ArrayList;
+import java.util.List;
final class BackStackState implements Parcelable {
final int[] mOps;
@@ -1055,7 +1056,7 @@
}
private static ArrayList<View> captureExitingViews(Transition exitTransition,
- Fragment outFragment, ArrayMap<String, View> namedViews) {
+ Fragment outFragment, ArrayMap<String, View> namedViews, View nonExistentView) {
ArrayList<View> viewList = null;
if (exitTransition != null) {
viewList = new ArrayList<View>();
@@ -1064,7 +1065,10 @@
if (namedViews != null) {
viewList.removeAll(namedViews.values());
}
- addTargets(exitTransition, viewList);
+ if (!viewList.isEmpty()) {
+ viewList.add(nonExistentView);
+ addTargets(exitTransition, viewList);
+ }
}
return viewList;
}
@@ -1132,11 +1136,8 @@
namedViews = mapSharedElementsIn(state, isBack, inFragment);
removeTargets(sharedElementTransition, sharedElementTargets);
sharedElementTargets.clear();
- if (namedViews.isEmpty()) {
- sharedElementTargets.add(state.nonExistentView);
- } else {
- sharedElementTargets.addAll(namedViews.values());
- }
+ sharedElementTargets.add(state.nonExistentView);
+ sharedElementTargets.addAll(namedViews.values());
addTargets(sharedElementTransition, sharedElementTargets);
@@ -1153,6 +1154,9 @@
if (namedViews != null) {
enteringViews.removeAll(namedViews.values());
}
+ enteringViews.add(state.nonExistentView);
+ // We added this earlier to prevent any views being targeted.
+ enterTransition.removeTarget(state.nonExistentView);
addTargets(enterTransition, enteringViews);
}
setSharedElementEpicenter(enterTransition, state);
@@ -1293,11 +1297,8 @@
ArrayList<View> sharedElementTargets = new ArrayList<View>();
if (sharedElementTransition != null) {
namedViews = remapSharedElements(state, outFragment, isBack);
- if (namedViews.isEmpty()) {
- sharedElementTargets.add(state.nonExistentView);
- } else {
- sharedElementTargets.addAll(namedViews.values());
- }
+ sharedElementTargets.add(state.nonExistentView);
+ sharedElementTargets.addAll(namedViews.values());
addTargets(sharedElementTransition, sharedElementTargets);
// Notify the start of the transition.
@@ -1310,7 +1311,7 @@
}
ArrayList<View> exitingViews = captureExitingViews(exitTransition, outFragment,
- namedViews);
+ namedViews, state.nonExistentView);
if (exitingViews == null || exitingViews.isEmpty()) {
exitTransition = null;
}
@@ -1388,20 +1389,69 @@
}
}
- private static void removeTargets(Transition transition, ArrayList<View> views) {
- int numViews = views.size();
- for (int i = 0; i < numViews; i++) {
- transition.removeTarget(views.get(i));
+ /**
+ * This method removes the views from transitions that target ONLY those views.
+ * The views list should match those added in addTargets and should contain
+ * one view that is not in the view hierarchy (state.nonExistentView).
+ */
+ public static void removeTargets(Transition transition, ArrayList<View> views) {
+ if (transition instanceof TransitionSet) {
+ TransitionSet set = (TransitionSet) transition;
+ int numTransitions = set.getTransitionCount();
+ for (int i = 0; i < numTransitions; i++) {
+ Transition child = set.getTransitionAt(i);
+ removeTargets(child, views);
+ }
+ } else if (!hasSimpleTarget(transition)) {
+ List<View> targets = transition.getTargets();
+ if (targets != null && targets.size() == views.size() &&
+ targets.containsAll(views)) {
+ // We have an exact match. We must have added these earlier in addTargets
+ for (int i = views.size() - 1; i >= 0; i--) {
+ transition.removeTarget(views.get(i));
+ }
+ }
}
}
- private static void addTargets(Transition transition, ArrayList<View> views) {
- int numViews = views.size();
- for (int i = 0; i < numViews; i++) {
- transition.addTarget(views.get(i));
+ /**
+ * This method adds views as targets to the transition, but only if the transition
+ * doesn't already have a target. It is best for views to contain one View object
+ * that does not exist in the view hierarchy (state.nonExistentView) so that
+ * when they are removed later, a list match will suffice to remove the targets.
+ * Otherwise, if you happened to have targeted the exact views for the transition,
+ * the removeTargets call will remove them unexpectedly.
+ */
+ public static void addTargets(Transition transition, ArrayList<View> views) {
+ if (transition instanceof TransitionSet) {
+ TransitionSet set = (TransitionSet) transition;
+ int numTransitions = set.getTransitionCount();
+ for (int i = 0; i < numTransitions; i++) {
+ Transition child = set.getTransitionAt(i);
+ addTargets(child, views);
+ }
+ } else if (!hasSimpleTarget(transition)) {
+ List<View> targets = transition.getTargets();
+ if (isNullOrEmpty(targets)) {
+ // We can just add the target views
+ int numViews = views.size();
+ for (int i = 0; i < numViews; i++) {
+ transition.addTarget(views.get(i));
+ }
+ }
}
}
+ private static boolean hasSimpleTarget(Transition transition) {
+ return !isNullOrEmpty(transition.getTargetIds()) ||
+ !isNullOrEmpty(transition.getTargetNames()) ||
+ !isNullOrEmpty(transition.getTargetTypes());
+ }
+
+ private static boolean isNullOrEmpty(List list) {
+ return list == null || list.isEmpty();
+ }
+
/**
* Remaps a name-to-View map, substituting different names for keys.
*
diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java
index 7fafc38..78cc810 100644
--- a/core/java/android/app/ContextImpl.java
+++ b/core/java/android/app/ContextImpl.java
@@ -92,6 +92,8 @@
import android.net.nsd.NsdManager;
import android.net.wifi.IWifiManager;
import android.net.wifi.WifiManager;
+import android.net.wifi.passpoint.IWifiPasspointManager;
+import android.net.wifi.passpoint.WifiPasspointManager;
import android.net.wifi.p2p.IWifiP2pManager;
import android.net.wifi.p2p.WifiP2pManager;
import android.net.wifi.IWifiScanner;
@@ -597,6 +599,13 @@
return new WifiManager(ctx.getOuterContext(), service);
}});
+ registerService(WIFI_PASSPOINT_SERVICE, new ServiceFetcher() {
+ public Object createService(ContextImpl ctx) {
+ IBinder b = ServiceManager.getService(WIFI_PASSPOINT_SERVICE);
+ IWifiPasspointManager service = IWifiPasspointManager.Stub.asInterface(b);
+ return new WifiPasspointManager(ctx.getOuterContext(), service);
+ }});
+
registerService(WIFI_P2P_SERVICE, new ServiceFetcher() {
public Object createService(ContextImpl ctx) {
IBinder b = ServiceManager.getService(WIFI_P2P_SERVICE);
diff --git a/core/java/android/app/Fragment.java b/core/java/android/app/Fragment.java
index af45731..ab28d95 100644
--- a/core/java/android/app/Fragment.java
+++ b/core/java/android/app/Fragment.java
@@ -219,8 +219,8 @@
* state of its view hierarchy has been restored.
* <li> {@link #onStart} makes the fragment visible to the user (based on its
* containing activity being started).
- * <li> {@link #onResume} makes the fragment interacting with the user (based on its
- * containing activity being resumed).
+ * <li> {@link #onResume} makes the fragment begin interacting with the user
+ * (based on its containing activity being resumed).
* </ol>
*
* <p>As a fragment is no longer being used, it goes through a reverse
@@ -564,7 +564,7 @@
* and later retrieved by the Fragment with {@link #getArguments}.
*
* <p>Applications should generally not implement a constructor. The
- * first place application code an run where the fragment is ready to
+ * first place application code can run where the fragment is ready to
* be used is in {@link #onAttach(Activity)}, the point where the fragment
* is actually associated with its activity. Some applications may also
* want to implement {@link #onInflate} to retrieve attributes from a
@@ -720,8 +720,7 @@
}
/**
- * Return the arguments supplied when the fragment was instantiated,
- * if any.
+ * Return the arguments supplied to {@link #setArguments}, if any.
*/
final public Bundle getArguments() {
return mArguments;
diff --git a/core/java/android/app/FragmentManager.java b/core/java/android/app/FragmentManager.java
index fc761fe..ccceef4 100644
--- a/core/java/android/app/FragmentManager.java
+++ b/core/java/android/app/FragmentManager.java
@@ -70,7 +70,7 @@
* with {@link FragmentTransaction#addToBackStack(String)
* FragmentTransaction.addToBackStack()}. Entries can later be
* retrieved with {@link FragmentManager#getBackStackEntryAt(int)
- * FragmentManager.getBackStackEntry()}.
+ * FragmentManager.getBackStackEntryAt()}.
*
* <p>Note that you should never hold on to a BackStackEntry object;
* the identifier as returned by {@link #getId} is the only thing that
@@ -260,7 +260,7 @@
/**
* Return the BackStackEntry at index <var>index</var> in the back stack;
- * entries start index 0 being the bottom of the stack.
+ * where the item on the bottom of the stack has index 0.
*/
public abstract BackStackEntry getBackStackEntryAt(int index);
diff --git a/core/java/android/app/FragmentTransaction.java b/core/java/android/app/FragmentTransaction.java
index 25cd3cc..dc7075c 100644
--- a/core/java/android/app/FragmentTransaction.java
+++ b/core/java/android/app/FragmentTransaction.java
@@ -26,7 +26,7 @@
/**
* Add a fragment to the activity state. This fragment may optionally
* also have its view (if {@link Fragment#onCreateView Fragment.onCreateView}
- * returns non-null) into a container view of the activity.
+ * returns non-null) inserted into a container view of the activity.
*
* @param containerViewId Optional identifier of the container this fragment is
* to be placed in. If 0, it will not be placed in a container.
diff --git a/core/java/android/app/IApplicationThread.java b/core/java/android/app/IApplicationThread.java
index f53075c..42acbc6 100644
--- a/core/java/android/app/IApplicationThread.java
+++ b/core/java/android/app/IApplicationThread.java
@@ -35,6 +35,7 @@
import android.os.IInterface;
import android.service.voice.IVoiceInteractionSession;
import com.android.internal.app.IVoiceInteractor;
+import com.android.internal.content.ReferrerIntent;
import java.io.FileDescriptor;
import java.util.List;
@@ -59,14 +60,14 @@
void scheduleSendResult(IBinder token, List<ResultInfo> results) throws RemoteException;
void scheduleLaunchActivity(Intent intent, IBinder token, int ident,
ActivityInfo info, Configuration curConfig, CompatibilityInfo compatInfo,
- IVoiceInteractor voiceInteractor, int procState, Bundle state,
+ String referrer, IVoiceInteractor voiceInteractor, int procState, Bundle state,
PersistableBundle persistentState, List<ResultInfo> pendingResults,
- List<Intent> pendingNewIntents, boolean notResumed, boolean isForward,
+ List<ReferrerIntent> pendingNewIntents, boolean notResumed, boolean isForward,
ProfilerInfo profilerInfo) throws RemoteException;
void scheduleRelaunchActivity(IBinder token, List<ResultInfo> pendingResults,
- List<Intent> pendingNewIntents, int configChanges,
+ List<ReferrerIntent> pendingNewIntents, int configChanges,
boolean notResumed, Configuration config) throws RemoteException;
- void scheduleNewIntent(List<Intent> intent, IBinder token) throws RemoteException;
+ void scheduleNewIntent(List<ReferrerIntent> intent, IBinder token) throws RemoteException;
void scheduleDestroyActivity(IBinder token, boolean finished,
int configChanges) throws RemoteException;
void scheduleReceiver(Intent intent, ActivityInfo info, CompatibilityInfo compatInfo,
diff --git a/core/java/android/app/Instrumentation.java b/core/java/android/app/Instrumentation.java
index 60a013e..d96153a 100644
--- a/core/java/android/app/Instrumentation.java
+++ b/core/java/android/app/Instrumentation.java
@@ -45,6 +45,7 @@
import android.view.MotionEvent;
import android.view.ViewConfiguration;
import android.view.Window;
+import com.android.internal.content.ReferrerIntent;
import java.io.File;
import java.util.ArrayList;
@@ -1042,7 +1043,7 @@
activity.attach(context, aThread, this, token, 0, application, intent,
info, title, parent, id,
(Activity.NonConfigurationInstances)lastNonConfigurationInstance,
- new Configuration(), null);
+ new Configuration(), null, null);
return activity;
}
@@ -1207,7 +1208,17 @@
* @param intent The new intent being received.
*/
public void callActivityOnNewIntent(Activity activity, Intent intent) {
- activity.onNewIntent(intent);
+ final String oldReferrer = activity.mReferrer;
+ try {
+ try {
+ activity.mReferrer = ((ReferrerIntent)intent).mReferrer;
+ } catch (ClassCastException e) {
+ activity.mReferrer = null;
+ }
+ activity.onNewIntent(intent);
+ } finally {
+ activity.mReferrer = oldReferrer;
+ }
}
/**
diff --git a/core/java/android/app/LocalActivityManager.java b/core/java/android/app/LocalActivityManager.java
index b654a6a..873e337 100644
--- a/core/java/android/app/LocalActivityManager.java
+++ b/core/java/android/app/LocalActivityManager.java
@@ -22,6 +22,7 @@
import android.os.Bundle;
import android.util.Log;
import android.view.Window;
+import com.android.internal.content.ReferrerIntent;
import java.util.ArrayList;
import java.util.HashMap;
@@ -310,8 +311,8 @@
if (aInfo.launchMode != ActivityInfo.LAUNCH_MULTIPLE ||
(intent.getFlags()&Intent.FLAG_ACTIVITY_SINGLE_TOP) != 0) {
// The activity wants onNewIntent() called.
- ArrayList<Intent> intents = new ArrayList<Intent>(1);
- intents.add(intent);
+ ArrayList<ReferrerIntent> intents = new ArrayList<>(1);
+ intents.add(new ReferrerIntent(intent, mParent.getPackageName()));
if (localLOGV) Log.v(TAG, r.id + ": new intent");
mActivityThread.performNewIntents(r, intents);
r.intent = intent;
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index 9157b1b..33cac75 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -3306,6 +3306,7 @@
* <p>The settings that can be updated by a profile or device owner with this method are:
* <ul>
* <li>{@link Settings.Secure#DEFAULT_INPUT_METHOD}</li>
+ * <li>{@link Settings.Secure#INSTALL_NON_MARKET_APPS}</li>
* <li>{@link Settings.Secure#SKIP_FIRST_USE_HINTS}</li>
* </ul>
* <p>A device owner can additionally update the following settings:
diff --git a/core/java/android/bluetooth/BluetoothHeadsetClientCall.java b/core/java/android/bluetooth/BluetoothHeadsetClientCall.java
index a15bd97..7b5a045 100644
--- a/core/java/android/bluetooth/BluetoothHeadsetClientCall.java
+++ b/core/java/android/bluetooth/BluetoothHeadsetClientCall.java
@@ -61,6 +61,7 @@
*/
public static final int CALL_STATE_TERMINATED = 7;
+ private final BluetoothDevice mDevice;
private final int mId;
private int mState;
private String mNumber;
@@ -70,8 +71,9 @@
/**
* Creates BluetoothHeadsetClientCall instance.
*/
- public BluetoothHeadsetClientCall(int id, int state, String number, boolean multiParty,
- boolean outgoing) {
+ public BluetoothHeadsetClientCall(BluetoothDevice device, int id, int state, String number,
+ boolean multiParty, boolean outgoing) {
+ mDevice = device;
mId = id;
mState = state;
mNumber = number != null ? number : "";
@@ -114,6 +116,15 @@
}
/**
+ * Gets call's device.
+ *
+ * @return call device.
+ */
+ public BluetoothDevice getDevice() {
+ return mDevice;
+ }
+
+ /**
* Gets call's Id.
*
* @return call id.
@@ -161,7 +172,9 @@
}
public String toString() {
- StringBuilder builder = new StringBuilder("BluetoothHeadsetClientCall{mId: ");
+ StringBuilder builder = new StringBuilder("BluetoothHeadsetClientCall{mDevice: ");
+ builder.append(mDevice);
+ builder.append(", mId: ");
builder.append(mId);
builder.append(", mState: ");
switch (mState) {
@@ -192,8 +205,9 @@
new Parcelable.Creator<BluetoothHeadsetClientCall>() {
@Override
public BluetoothHeadsetClientCall createFromParcel(Parcel in) {
- return new BluetoothHeadsetClientCall(in.readInt(), in.readInt(),
- in.readString(), in.readInt() == 1, in.readInt() == 1);
+ return new BluetoothHeadsetClientCall((BluetoothDevice)in.readParcelable(null),
+ in.readInt(), in.readInt(), in.readString(),
+ in.readInt() == 1, in.readInt() == 1);
}
@Override
@@ -204,6 +218,7 @@
@Override
public void writeToParcel(Parcel out, int flags) {
+ out.writeParcelable(mDevice, 0);
out.writeInt(mId);
out.writeInt(mState);
out.writeString(mNumber);
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index e06f034..57f6028 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -1401,14 +1401,36 @@
= "android.intent.extra.ORIGINATING_URI";
/**
- * Used as a URI extra field with {@link #ACTION_INSTALL_PACKAGE} and
- * {@link #ACTION_VIEW} to indicate the HTTP referrer URI associated with the Intent
- * data field or {@link #EXTRA_ORIGINATING_URI}.
+ * This extra can be used with any Intent used to launch an activity, supplying information
+ * about who is launching that activity. This field contains a {@link android.net.Uri}
+ * object, typically an http: or https: URI of the web site that the referral came from;
+ * it can also use the {@link #URI_ANDROID_APP_SCHEME android-app:} scheme to identify
+ * a native application that it came from.
+ *
+ * <p>To retrieve this value in a client, use {@link android.app.Activity#getReferrer}
+ * instead of directly retrieving the extra. It is also valid for applications to
+ * instead supply {@link #EXTRA_REFERRER_NAME} for cases where they can only create
+ * a string, not a Uri; the field here, if supplied, will always take precedence,
+ * however.</p>
+ *
+ * @see #EXTRA_REFERRER_NAME
*/
public static final String EXTRA_REFERRER
= "android.intent.extra.REFERRER";
/**
+ * Alternate version of {@link #EXTRA_REFERRER} that supplies the URI as a String rather
+ * than a {@link android.net.Uri} object. Only for use in cases where Uri objects can
+ * not be created, in particular when Intent extras are supplied through the
+ * {@link #URI_INTENT_SCHEME intent:} or {@link #URI_ANDROID_APP_SCHEME android-app:}
+ * schemes.
+ *
+ * @see #EXTRA_REFERRER
+ */
+ public static final String EXTRA_REFERRER_NAME
+ = "android.intent.extra.REFERRER_NAME";
+
+ /**
* Used as an int extra field with {@link #ACTION_INSTALL_PACKAGE} and
* {@link} #ACTION_VIEW} to indicate the uid of the package that initiated the install
* @hide
@@ -3919,6 +3941,75 @@
*/
public static final int URI_INTENT_SCHEME = 1<<0;
+ /**
+ * Flag for use with {@link #toUri} and {@link #parseUri}: the URI string
+ * always has the "android-app:" scheme. This is a variation of
+ * {@link #URI_INTENT_SCHEME} whose format is simpler for the case of an
+ * http/https URI being delivered to a specific package name. The format
+ * is:
+ *
+ * <pre class="prettyprint">
+ * android-app://{package_id}/{scheme}/{host}/{path}{#Intent;...}</pre>
+ *
+ * <p>In this scheme, only the <code>pacakge_id</code> is required, and all
+ * other components can be included as desired. Note that this can not be
+ * used with intents that have a {@link #setSelector}, since the base intent
+ * will always have an explicit package name.</p>
+ *
+ * <p>Some examples of how this scheme maps to Intent objects:</p>
+ * <table border="2" width="85%" align="center" frame="hsides" rules="rows">
+ * <colgroup align="left" />
+ * <colgroup align="left" />
+ * <thead>
+ * <tr><th>URI</th> <th>Intent</th></tr>
+ * </thead>
+ *
+ * <tbody>
+ * <tr><td><code>android-app://com.example.app</code></td>
+ * <td><table style="margin:0;border:0;cellpadding:0;cellspacing:0">
+ * <tr><td>Action: </td><td>{@link #ACTION_MAIN}</td></tr>
+ * <tr><td>Package: </td><td><code>com.example.app</code></td></tr>
+ * </table></td>
+ * </tr>
+ * <tr><td><code>android-app://com.example.app/http/example.com</code></td>
+ * <td><table style="margin:0;border:0;cellpadding:0;cellspacing:0">
+ * <tr><td>Action: </td><td>{@link #ACTION_VIEW}</td></tr>
+ * <tr><td>Data: </td><td><code>http://example.com/</code></td></tr>
+ * <tr><td>Package: </td><td><code>com.example.app</code></td></tr>
+ * </table></td>
+ * </tr>
+ * <tr><td><code>android-app://com.example.app/http/example.com/foo?1234</code></td>
+ * <td><table style="margin:0;border:0;cellpadding:0;cellspacing:0">
+ * <tr><td>Action: </td><td>{@link #ACTION_VIEW}</td></tr>
+ * <tr><td>Data: </td><td><code>http://example.com/foo?1234</code></td></tr>
+ * <tr><td>Package: </td><td><code>com.example.app</code></td></tr>
+ * </table></td>
+ * </tr>
+ * <tr><td><code>android-app://com.example.app/<br />#Intent;action=com.example.MY_ACTION;end</code></td>
+ * <td><table style="margin:0;border:0;cellpadding:0;cellspacing:0">
+ * <tr><td>Action: </td><td><code>com.example.MY_ACTION</code></td></tr>
+ * <tr><td>Package: </td><td><code>com.example.app</code></td></tr>
+ * </table></td>
+ * </tr>
+ * <tr><td><code>android-app://com.example.app/http/example.com/foo?1234<br />#Intent;action=com.example.MY_ACTION;end</code></td>
+ * <td><table style="margin:0;border:0;cellpadding:0;cellspacing:0">
+ * <tr><td>Action: </td><td><code>com.example.MY_ACTION</code></td></tr>
+ * <tr><td>Data: </td><td><code>http://example.com/foo?1234</code></td></tr>
+ * <tr><td>Package: </td><td><code>com.example.app</code></td></tr>
+ * </table></td>
+ * </tr>
+ * <tr><td><code>android-app://com.example.app/<br />#Intent;action=com.example.MY_ACTION;<br />i.some_int=100;S.some_str=hello;end</code></td>
+ * <td><table border="" style="margin:0" >
+ * <tr><td>Action: </td><td><code>com.example.MY_ACTION</code></td></tr>
+ * <tr><td>Package: </td><td><code>com.example.app</code></td></tr>
+ * <tr><td>Extras: </td><td><code>some_int=(int)100<br />some_str=(String)hello</code></td></tr>
+ * </table></td>
+ * </tr>
+ * </tbody>
+ * </table>
+ */
+ public static final int URI_ANDROID_APP_SCHEME = 1<<1;
+
// ---------------------------------------------------------------------
private String mAction;
@@ -4179,8 +4270,8 @@
* the scheme and full path.
*
* @param uri The URI to turn into an Intent.
- * @param flags Additional processing flags. Either 0 or
- * {@link #URI_INTENT_SCHEME}.
+ * @param flags Additional processing flags. Either 0,
+ * {@link #URI_INTENT_SCHEME}, or {@link #URI_ANDROID_APP_SCHEME}.
*
* @return Intent The newly created Intent object.
*
@@ -4193,9 +4284,11 @@
public static Intent parseUri(String uri, int flags) throws URISyntaxException {
int i = 0;
try {
- // Validate intent scheme for if requested.
- if ((flags&URI_INTENT_SCHEME) != 0) {
- if (!uri.startsWith("intent:")) {
+ final boolean androidApp = uri.startsWith("android-app:");
+
+ // Validate intent scheme if requested.
+ if ((flags&(URI_INTENT_SCHEME|URI_ANDROID_APP_SCHEME)) != 0) {
+ if (!uri.startsWith("intent:") && !androidApp) {
Intent intent = new Intent(ACTION_VIEW);
try {
intent.setData(Uri.parse(uri));
@@ -4206,24 +4299,40 @@
}
}
- // simple case
i = uri.lastIndexOf("#");
- if (i == -1) return new Intent(ACTION_VIEW, Uri.parse(uri));
+ // simple case
+ if (i == -1) {
+ if (!androidApp) {
+ return new Intent(ACTION_VIEW, Uri.parse(uri));
+ }
// old format Intent URI
- if (!uri.startsWith("#Intent;", i)) return getIntentOld(uri);
+ } else if (!uri.startsWith("#Intent;", i)) {
+ if (!androidApp) {
+ return getIntentOld(uri);
+ } else {
+ i = -1;
+ }
+ }
// new format
Intent intent = new Intent(ACTION_VIEW);
Intent baseIntent = intent;
+ boolean explicitAction = false;
+ boolean inSelector = false;
// fetch data part, if present
- String data = i >= 0 ? uri.substring(0, i) : null;
String scheme = null;
- i += "#Intent;".length();
+ String data;
+ if (i >= 0) {
+ data = uri.substring(0, i);
+ i += 8; // length of "#Intent;"
+ } else {
+ data = uri;
+ }
// loop over contents of Intent, all name=value;
- while (!uri.startsWith("end", i)) {
+ while (i >= 0 && !uri.startsWith("end", i)) {
int eq = uri.indexOf('=', i);
if (eq < 0) eq = i-1;
int semi = uri.indexOf(';', i);
@@ -4232,6 +4341,9 @@
// action
if (uri.startsWith("action=", i)) {
intent.setAction(value);
+ if (!inSelector) {
+ explicitAction = true;
+ }
}
// categories
@@ -4261,7 +4373,11 @@
// scheme
else if (uri.startsWith("scheme=", i)) {
- scheme = value;
+ if (inSelector) {
+ intent.mData = Uri.parse(value);
+ } else {
+ scheme = value;
+ }
}
// source bounds
@@ -4272,6 +4388,7 @@
// selector
else if (semi == (i+3) && uri.startsWith("SEL", i)) {
intent = new Intent();
+ inSelector = true;
}
// extra
@@ -4297,9 +4414,11 @@
i = semi + 1;
}
- if (intent != baseIntent) {
+ if (inSelector) {
// The Intent had a selector; fix it up.
- baseIntent.setSelector(intent);
+ if (baseIntent.mPackage == null) {
+ baseIntent.setSelector(intent);
+ }
intent = baseIntent;
}
@@ -4309,6 +4428,47 @@
if (scheme != null) {
data = scheme + ':' + data;
}
+ } else if (data.startsWith("android-app:")) {
+ if (data.charAt(12) == '/' && data.charAt(13) == '/') {
+ // Correctly formed android-app, first part is package name.
+ int end = data.indexOf('/', 14);
+ if (end < 0) {
+ // All we have is a package name.
+ intent.mPackage = data.substring(14);
+ if (!explicitAction) {
+ intent.setAction(ACTION_MAIN);
+ }
+ data = "";
+ } else {
+ // Target the Intent at the given package name always.
+ String authority = null;
+ intent.mPackage = data.substring(14, end);
+ int newEnd;
+ if (end < data.length() && (newEnd=data.indexOf('/', end+1)) >= 0) {
+ // Found a scheme, remember it.
+ scheme = data.substring(end+1, newEnd);
+ end = newEnd;
+ if (end < data.length() && (newEnd=data.indexOf('/', end+1)) >= 0) {
+ // Found a authority, remember it.
+ authority = data.substring(end+1, newEnd);
+ end = newEnd;
+ }
+ }
+ if (scheme == null) {
+ // If there was no scheme, then this just targets the package.
+ if (!explicitAction) {
+ intent.setAction(ACTION_MAIN);
+ }
+ data = "";
+ } else if (authority == null) {
+ data = scheme + ":";
+ } else {
+ data = scheme + "://" + authority + data.substring(end);
+ }
+ }
+ } else {
+ data = "";
+ }
}
if (data.length() > 0) {
@@ -7084,14 +7244,53 @@
* <p>You can convert the returned string back to an Intent with
* {@link #getIntent}.
*
- * @param flags Additional operating flags. Either 0 or
- * {@link #URI_INTENT_SCHEME}.
+ * @param flags Additional operating flags. Either 0,
+ * {@link #URI_INTENT_SCHEME}, or {@link #URI_ANDROID_APP_SCHEME}.
*
* @return Returns a URI encoding URI string describing the entire contents
* of the Intent.
*/
public String toUri(int flags) {
StringBuilder uri = new StringBuilder(128);
+ if ((flags&URI_ANDROID_APP_SCHEME) != 0) {
+ if (mPackage == null) {
+ throw new IllegalArgumentException(
+ "Intent must include an explicit package name to build an android-app: "
+ + this);
+ }
+ uri.append("android-app://");
+ uri.append(mPackage);
+ String scheme = null;
+ if (mData != null) {
+ scheme = mData.getScheme();
+ if (scheme != null) {
+ uri.append('/');
+ uri.append(scheme);
+ String authority = mData.getEncodedAuthority();
+ if (authority != null) {
+ uri.append('/');
+ uri.append(authority);
+ String path = mData.getEncodedPath();
+ if (path != null) {
+ uri.append(path);
+ }
+ String queryParams = mData.getEncodedQuery();
+ if (queryParams != null) {
+ uri.append('?');
+ uri.append(queryParams);
+ }
+ String fragment = mData.getEncodedFragment();
+ if (fragment != null) {
+ uri.append('#');
+ uri.append(fragment);
+ }
+ }
+ }
+ }
+ toUriFragment(uri, null, scheme == null ? Intent.ACTION_MAIN : Intent.ACTION_VIEW,
+ mPackage, flags);
+ return uri.toString();
+ }
String scheme = null;
if (mData != null) {
String data = mData.toString();
@@ -7121,27 +7320,38 @@
uri.append("intent:");
}
- uri.append("#Intent;");
+ toUriFragment(uri, scheme, Intent.ACTION_VIEW, null, flags);
- toUriInner(uri, scheme, flags);
+ return uri.toString();
+ }
+
+ private void toUriFragment(StringBuilder uri, String scheme, String defAction,
+ String defPackage, int flags) {
+ StringBuilder frag = new StringBuilder(128);
+
+ toUriInner(frag, scheme, defAction, defPackage, flags);
if (mSelector != null) {
uri.append("SEL;");
// Note that for now we are not going to try to handle the
// data part; not clear how to represent this as a URI, and
// not much utility in it.
- mSelector.toUriInner(uri, null, flags);
+ mSelector.toUriInner(frag, mSelector.mData != null ? mSelector.mData.getScheme() : null,
+ null, null, flags);
}
- uri.append("end");
-
- return uri.toString();
+ if (frag.length() > 0) {
+ uri.append("#Intent;");
+ uri.append(frag);
+ uri.append("end");
+ }
}
- private void toUriInner(StringBuilder uri, String scheme, int flags) {
+ private void toUriInner(StringBuilder uri, String scheme, String defAction,
+ String defPackage, int flags) {
if (scheme != null) {
uri.append("scheme=").append(scheme).append(';');
}
- if (mAction != null) {
+ if (mAction != null && !mAction.equals(defAction)) {
uri.append("action=").append(Uri.encode(mAction)).append(';');
}
if (mCategories != null) {
@@ -7155,7 +7365,7 @@
if (mFlags != 0) {
uri.append("launchFlags=0x").append(Integer.toHexString(mFlags)).append(';');
}
- if (mPackage != null) {
+ if (mPackage != null && !mPackage.equals(defPackage)) {
uri.append("package=").append(Uri.encode(mPackage)).append(';');
}
if (mComponent != null) {
diff --git a/cmds/app_process/sigchain_proxy.cpp b/core/java/android/content/pm/LabeledIntent.aidl
similarity index 76%
copy from cmds/app_process/sigchain_proxy.cpp
copy to core/java/android/content/pm/LabeledIntent.aidl
index bb7a678..ad96759 100644
--- a/cmds/app_process/sigchain_proxy.cpp
+++ b/core/java/android/content/pm/LabeledIntent.aidl
@@ -1,11 +1,11 @@
/*
- * Copyright (C) 2014 The Android Open Source Project
+ * Copyright 2014, The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
- * http://www.apache.org/licenses/LICENSE-2.0
+ * 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,
@@ -14,4 +14,6 @@
* limitations under the License.
*/
-#include "sigchainlib/sigchain.cc"
+package android.content.pm;
+
+parcelable LabeledIntent;
diff --git a/core/java/android/gesture/GestureOverlayView.java b/core/java/android/gesture/GestureOverlayView.java
index 6e3a00f..e1a2a25 100644
--- a/core/java/android/gesture/GestureOverlayView.java
+++ b/core/java/android/gesture/GestureOverlayView.java
@@ -640,7 +640,7 @@
mStrokeBuffer.add(new GesturePoint(x, y, event.getEventTime()));
if (mHandleGestureActions && !mIsGesturing) {
- mTotalLength += (float) Math.sqrt(dx * dx + dy * dy);
+ mTotalLength += (float) Math.hypot(dx, dy);
if (mTotalLength > mGestureStrokeLengthThreshold) {
final OrientedBoundingBox box =
diff --git a/core/java/android/gesture/GestureStroke.java b/core/java/android/gesture/GestureStroke.java
index 1d0f0fe..4a324f9 100644
--- a/core/java/android/gesture/GestureStroke.java
+++ b/core/java/android/gesture/GestureStroke.java
@@ -69,8 +69,7 @@
bx.bottom = p.y;
len = 0;
} else {
- len += Math.sqrt(Math.pow(p.x - tmpPoints[(i - 1) * 2], 2)
- + Math.pow(p.y - tmpPoints[(i -1 ) * 2 + 1], 2));
+ len += Math.hypot(p.x - tmpPoints[(i - 1) * 2], p.y - tmpPoints[(i -1) * 2 + 1]);
bx.union(p.x, p.y);
}
index++;
diff --git a/core/java/android/gesture/GestureUtils.java b/core/java/android/gesture/GestureUtils.java
index dd221fc..416279e 100644
--- a/core/java/android/gesture/GestureUtils.java
+++ b/core/java/android/gesture/GestureUtils.java
@@ -293,7 +293,7 @@
}
float deltaX = currentPointX - lstPointX;
float deltaY = currentPointY - lstPointY;
- float distance = (float) Math.sqrt(deltaX * deltaX + deltaY * deltaY);
+ float distance = (float) Math.hypot(deltaX, deltaY);
if (distanceSoFar + distance >= increment) {
float ratio = (increment - distanceSoFar) / distance;
float nx = lstPointX + ratio * deltaX;
@@ -379,7 +379,7 @@
for (int i = 0; i < count; i += 2) {
float dx = points[i + 2] - points[i];
float dy = points[i + 3] - points[i + 1];
- sum += Math.sqrt(dx * dx + dy * dy);
+ sum += Math.hypot(dx, dy);
}
return sum;
}
@@ -388,13 +388,13 @@
float totalLen = computeTotalLength(points);
float dx = points[2] - points[0];
float dy = points[3] - points[1];
- return (float) Math.sqrt(dx * dx + dy * dy) / totalLen;
+ return (float) Math.hypot(dx, dy) / totalLen;
}
static float computeStraightness(float[] points, float totalLen) {
float dx = points[2] - points[0];
float dy = points[3] - points[1];
- return (float) Math.sqrt(dx * dx + dy * dy) / totalLen;
+ return (float) Math.hypot(dx, dy) / totalLen;
}
/**
diff --git a/core/java/android/hardware/GeomagneticField.java b/core/java/android/hardware/GeomagneticField.java
index ef05732..eb26ee5 100644
--- a/core/java/android/hardware/GeomagneticField.java
+++ b/core/java/android/hardware/GeomagneticField.java
@@ -281,7 +281,7 @@
* @return Horizontal component of the field strength in nonoteslas.
*/
public float getHorizontalStrength() {
- return (float) Math.sqrt(mX * mX + mY * mY);
+ return (float) Math.hypot(mX, mY);
}
/**
diff --git a/core/java/android/net/LocalSocket.java b/core/java/android/net/LocalSocket.java
index 31bc20b..a374a86 100644
--- a/core/java/android/net/LocalSocket.java
+++ b/core/java/android/net/LocalSocket.java
@@ -29,7 +29,7 @@
*/
public class LocalSocket implements Closeable {
- private LocalSocketImpl impl;
+ private final LocalSocketImpl impl;
private volatile boolean implCreated;
private LocalSocketAddress localAddress;
private boolean isBound;
diff --git a/core/java/android/net/Proxy.java b/core/java/android/net/Proxy.java
index 3477b02..17a84a7 100644
--- a/core/java/android/net/Proxy.java
+++ b/core/java/android/net/Proxy.java
@@ -22,8 +22,6 @@
import android.text.TextUtils;
import android.util.Log;
-import org.apache.http.HttpHost;
-
import java.net.InetSocketAddress;
import java.net.ProxySelector;
import java.net.URI;
@@ -37,8 +35,6 @@
*/
public final class Proxy {
- // Set to true to enable extra debugging.
- private static final boolean DEBUG = false;
private static final String TAG = "Proxy";
private static final ProxySelector sDefaultProxySelector;
@@ -192,31 +188,6 @@
}
}
- /**
- * Returns the preferred proxy to be used by clients. This is a wrapper
- * around {@link android.net.Proxy#getHost()}.
- *
- * @param context the context which will be passed to
- * {@link android.net.Proxy#getHost()}
- * @param url the target URL for the request
- * @note Calling this method requires permission
- * android.permission.ACCESS_NETWORK_STATE
- * @return The preferred proxy to be used by clients, or null if there
- * is no proxy.
- * {@hide}
- */
- // TODO: Get rid of this method. It's used only in tests.
- public static final HttpHost getPreferredHttpHost(Context context,
- String url) {
- java.net.Proxy prefProxy = getProxy(context, url);
- if (prefProxy.equals(java.net.Proxy.NO_PROXY)) {
- return null;
- } else {
- InetSocketAddress sa = (InetSocketAddress)prefProxy.address();
- return new HttpHost(sa.getHostName(), sa.getPort(), "http");
- }
- }
-
private static final boolean isLocalHost(String host) {
if (host == null) {
return false;
diff --git a/core/java/android/net/SSLCertificateSocketFactory.java b/core/java/android/net/SSLCertificateSocketFactory.java
index c15e6e5..6654577 100644
--- a/core/java/android/net/SSLCertificateSocketFactory.java
+++ b/core/java/android/net/SSLCertificateSocketFactory.java
@@ -208,7 +208,7 @@
private SSLSocketFactory makeSocketFactory(
KeyManager[] keyManagers, TrustManager[] trustManagers) {
try {
- OpenSSLContextImpl sslContext = new OpenSSLContextImpl();
+ OpenSSLContextImpl sslContext = OpenSSLContextImpl.getPreferred();
sslContext.engineInit(keyManagers, trustManagers, null);
sslContext.engineGetClientSessionContext().setPersistentCache(mSessionCache);
return sslContext.engineGetSocketFactory();
diff --git a/core/java/android/net/http/HttpsConnection.java b/core/java/android/net/http/HttpsConnection.java
index 6bf01e2..a8674de 100644
--- a/core/java/android/net/http/HttpsConnection.java
+++ b/core/java/android/net/http/HttpsConnection.java
@@ -79,7 +79,7 @@
cache = FileClientSessionCache.usingDirectory(sessionDir);
}
- OpenSSLContextImpl sslContext = new OpenSSLContextImpl();
+ OpenSSLContextImpl sslContext = OpenSSLContextImpl.getPreferred();
// here, trust managers is a single trust-all manager
TrustManager[] trustManagers = new TrustManager[] {
diff --git a/core/java/android/os/Build.java b/core/java/android/os/Build.java
index f361695b..72d61e8 100644
--- a/core/java/android/os/Build.java
+++ b/core/java/android/os/Build.java
@@ -515,7 +515,8 @@
* <p>Applications targeting this or a later release will get these
* new changes in behavior:</p>
* <ul>
- * <li> The default result of {android.preference.PreferenceActivity#isValidFragment
+ * <li> The default result of
+ * {@link android.preference.PreferenceActivity#isValidFragment(String)
* PreferenceActivity.isValueFragment} becomes false instead of true.</li>
* <li> In {@link android.webkit.WebView}, apps targeting earlier versions will have
* JS URLs evaluated directly and any result of the evaluation will not replace
diff --git a/core/java/android/os/Debug.java b/core/java/android/os/Debug.java
index 3f42d25..eb74c63 100644
--- a/core/java/android/os/Debug.java
+++ b/core/java/android/os/Debug.java
@@ -1282,7 +1282,10 @@
* + icount.globalMethodInvocations());
* }
* </pre>
+ *
+ * @deprecated Instruction counting is no longer supported.
*/
+ @Deprecated
public static class InstructionCount {
private static final int NUM_INSTR =
OpcodeInfo.MAXIMUM_PACKED_VALUE + 1;
diff --git a/core/java/android/os/IPowerManager.aidl b/core/java/android/os/IPowerManager.aidl
index ec30684..16dac7d 100644
--- a/core/java/android/os/IPowerManager.aidl
+++ b/core/java/android/os/IPowerManager.aidl
@@ -49,7 +49,6 @@
void crash(String message);
void setStayOnSetting(int val);
- void setMaximumScreenOffTimeoutFromDeviceAdmin(int timeMs);
void boostScreenBrightness(long time);
// temporarily overrides the screen brightness settings to allow the user to
diff --git a/core/java/android/os/PowerManagerInternal.java b/core/java/android/os/PowerManagerInternal.java
index 14f4a83..9d78360 100644
--- a/core/java/android/os/PowerManagerInternal.java
+++ b/core/java/android/os/PowerManagerInternal.java
@@ -56,6 +56,13 @@
public abstract void setUserActivityTimeoutOverrideFromWindowManager(long timeoutMillis);
/**
+ * Used by device administration to set the maximum screen off timeout.
+ *
+ * This method must only be called by the device administration policy manager.
+ */
+ public abstract void setMaximumScreenOffTimeoutFromDeviceAdmin(int timeMs);
+
+ /**
* Used by the dream manager to override certain properties while dozing.
*
* @param screenState The overridden screen state, or {@link Display.STATE_UNKNOWN}
diff --git a/core/java/android/provider/DocumentsProvider.java b/core/java/android/provider/DocumentsProvider.java
index 270d786..932e873 100644
--- a/core/java/android/provider/DocumentsProvider.java
+++ b/core/java/android/provider/DocumentsProvider.java
@@ -355,7 +355,7 @@
}
/**
- * Return documents that that match the given query under the requested
+ * Return documents that match the given query under the requested
* root. The returned documents should be sorted by relevance in descending
* order. How documents are matched against the query string is an
* implementation detail left to each provider, but it's suggested that at
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 88c3897..8585682 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -308,7 +308,7 @@
/**
* Activity Action: Show settings to allow configuration of
- * cast endpoints.
+ * {@link android.media.routing.MediaRouteService media route providers}.
* <p>
* In some cases, a matching Activity may not exist, so ensure you
* safeguard against this.
@@ -6363,6 +6363,14 @@
"preferred_network_mode";
/**
+ * Setting to 1 will hide carrier network settings.
+ * Default is 0.
+ * @hide
+ */
+ public static final String HIDE_CARRIER_NETWORK_SETTINGS =
+ "hide_carrier_network_settings";
+
+ /**
* Name of an application package to be debugged.
*/
public static final String DEBUG_APP = "debug_app";
diff --git a/core/java/android/text/BoringLayout.java b/core/java/android/text/BoringLayout.java
index 6f00707..e78cf8f 100644
--- a/core/java/android/text/BoringLayout.java
+++ b/core/java/android/text/BoringLayout.java
@@ -20,7 +20,6 @@
import android.graphics.Paint;
import android.graphics.Path;
import android.text.style.ParagraphStyle;
-import android.util.FloatMath;
/**
* A BoringLayout is a very simple Layout implementation for text that
@@ -207,7 +206,7 @@
TextLine line = TextLine.obtain();
line.set(paint, source, 0, source.length(), Layout.DIR_LEFT_TO_RIGHT,
Layout.DIRS_ALL_LEFT_TO_RIGHT, false, null);
- mMax = (int) FloatMath.ceil(line.metrics(null));
+ mMax = (int) Math.ceil(line.metrics(null));
TextLine.recycle(line);
}
@@ -301,7 +300,7 @@
TextLine line = TextLine.obtain();
line.set(paint, text, 0, length, Layout.DIR_LEFT_TO_RIGHT,
Layout.DIRS_ALL_LEFT_TO_RIGHT, false, null);
- fm.width = (int) FloatMath.ceil(line.metrics(fm));
+ fm.width = (int) Math.ceil(line.metrics(fm));
TextLine.recycle(line);
return fm;
diff --git a/core/java/android/text/Html.java b/core/java/android/text/Html.java
index 2fcc597..dc93bc2 100644
--- a/core/java/android/text/Html.java
+++ b/core/java/android/text/Html.java
@@ -61,7 +61,7 @@
*/
public static interface ImageGetter {
/**
- * This methos is called when the HTML parser encounters an
+ * This method is called when the HTML parser encounters an
* <img> tag. The <code>source</code> argument is the
* string from the "src" attribute; the return value should be
* a Drawable representation of the image or <code>null</code>
diff --git a/core/java/android/text/StaticLayout.java b/core/java/android/text/StaticLayout.java
index e82057c..70ad3f0 100644
--- a/core/java/android/text/StaticLayout.java
+++ b/core/java/android/text/StaticLayout.java
@@ -28,6 +28,8 @@
import com.android.internal.util.ArrayUtils;
import com.android.internal.util.GrowingArrayUtils;
+import java.util.Arrays;
+
/**
* StaticLayout is a Layout for text that will not be edited after it
* is laid out. Use {@link DynamicLayout} for text that may change.
@@ -161,7 +163,12 @@
float spacingadd, boolean includepad,
boolean trackpad, float ellipsizedWidth,
TextUtils.TruncateAt ellipsize) {
- int[] breakOpp = null;
+ LineBreaks lineBreaks = new LineBreaks();
+ // store span end locations
+ int[] spanEndCache = new int[4];
+ // store fontMetrics per span range
+ // must be a multiple of 4 (and > 0) (store top, bottom, ascent, and descent per range)
+ int[] fmCache = new int[4 * 4];
final String localeLanguageTag = paint.getTextLocale().toLanguageTag();
mLineCount = 0;
@@ -186,7 +193,7 @@
else
paraEnd++;
- int firstWidthLineLimit = mLineCount + 1;
+ int firstWidthLineCount = 1;
int firstWidth = outerWidth;
int restWidth = outerWidth;
@@ -204,9 +211,8 @@
// leading margin spans, not just this particular one
if (lms instanceof LeadingMarginSpan2) {
LeadingMarginSpan2 lms2 = (LeadingMarginSpan2) lms;
- int lmsFirstLine = getLineForOffset(spanned.getSpanStart(lms2));
- firstWidthLineLimit = Math.max(firstWidthLineLimit,
- lmsFirstLine + lms2.getLeadingMarginLineCount());
+ firstWidthLineCount = Math.max(firstWidthLineCount,
+ lms2.getLeadingMarginLineCount());
}
}
@@ -242,34 +248,23 @@
int dir = measured.mDir;
boolean easy = measured.mEasy;
- breakOpp = nLineBreakOpportunities(localeLanguageTag, chs, paraEnd - paraStart, breakOpp);
- int breakOppIndex = 0;
-
- int width = firstWidth;
-
- float w = 0;
- // here is the offset of the starting character of the line we are currently measuring
- int here = paraStart;
-
- // ok is a character offset located after a word separator (space, tab, number...) where
- // we would prefer to cut the current line. Equals to here when no such break was found.
- int ok = paraStart;
- float okWidth = w;
- int okAscent = 0, okDescent = 0, okTop = 0, okBottom = 0;
-
- // fit is a character offset such that the [here, fit[ range fits in the allowed width.
- // We will cut the line there if no ok position is found.
- int fit = paraStart;
- float fitWidth = w;
- int fitAscent = 0, fitDescent = 0, fitTop = 0, fitBottom = 0;
- // same as fitWidth but not including any trailing whitespace
- float fitWidthGraphing = w;
-
- boolean hasTabOrEmoji = false;
- boolean hasTab = false;
- TabStops tabStops = null;
-
+ // measurement has to be done before performing line breaking
+ // but we don't want to recompute fontmetrics or span ranges the
+ // second time, so we cache those and then use those stored values
+ int fmCacheCount = 0;
+ int spanEndCacheCount = 0;
for (int spanStart = paraStart, spanEnd; spanStart < paraEnd; spanStart = spanEnd) {
+ if (fmCacheCount * 4 >= fmCache.length) {
+ int[] grow = new int[fmCacheCount * 4 * 2];
+ System.arraycopy(fmCache, 0, grow, 0, fmCacheCount * 4);
+ fmCache = grow;
+ }
+
+ if (spanEndCacheCount >= spanEndCache.length) {
+ int[] grow = new int[spanEndCacheCount * 2];
+ System.arraycopy(spanEndCache, 0, grow, 0, spanEndCacheCount);
+ spanEndCache = grow;
+ }
if (spanned == null) {
spanEnd = paraEnd;
@@ -285,201 +280,109 @@
measured.addStyleRun(paint, spans, spanLen, fm);
}
- int fmTop = fm.top;
- int fmBottom = fm.bottom;
- int fmAscent = fm.ascent;
- int fmDescent = fm.descent;
+ // the order of storage here (top, bottom, ascent, descent) has to match the code below
+ // where these values are retrieved
+ fmCache[fmCacheCount * 4 + 0] = fm.top;
+ fmCache[fmCacheCount * 4 + 1] = fm.bottom;
+ fmCache[fmCacheCount * 4 + 2] = fm.ascent;
+ fmCache[fmCacheCount * 4 + 3] = fm.descent;
+ fmCacheCount++;
- for (int j = spanStart; j < spanEnd; j++) {
- char c = chs[j - paraStart];
+ spanEndCache[spanEndCacheCount] = spanEnd;
+ spanEndCacheCount++;
+ }
- if (c == CHAR_NEW_LINE) {
- // intentionally left empty
- } else if (c == CHAR_TAB) {
- if (hasTab == false) {
- hasTab = true;
- hasTabOrEmoji = true;
- if (spanned != null) {
- // First tab this para, check for tabstops
- TabStopSpan[] spans = getParagraphSpans(spanned, paraStart,
- paraEnd, TabStopSpan.class);
- if (spans.length > 0) {
- tabStops = new TabStops(TAB_INCREMENT, spans);
- }
- }
- }
- if (tabStops != null) {
- w = tabStops.nextTab(w);
- } else {
- w = TabStops.nextDefaultStop(w, TAB_INCREMENT);
- }
- } else if (c >= CHAR_FIRST_HIGH_SURROGATE && c <= CHAR_LAST_LOW_SURROGATE
- && j + 1 < spanEnd) {
- int emoji = Character.codePointAt(chs, j - paraStart);
-
- if (emoji >= MIN_EMOJI && emoji <= MAX_EMOJI) {
- Bitmap bm = EMOJI_FACTORY.getBitmapFromAndroidPua(emoji);
-
- if (bm != null) {
- Paint whichPaint;
-
- if (spanned == null) {
- whichPaint = paint;
- } else {
- whichPaint = mWorkPaint;
- }
-
- float wid = bm.getWidth() * -whichPaint.ascent() / bm.getHeight();
-
- w += wid;
- hasTabOrEmoji = true;
- j++;
- } else {
- w += widths[j - paraStart];
- }
- } else {
- w += widths[j - paraStart];
- }
- } else {
- w += widths[j - paraStart];
+ // tab stop locations
+ int[] variableTabStops = null;
+ if (spanned != null) {
+ TabStopSpan[] spans = getParagraphSpans(spanned, paraStart,
+ paraEnd, TabStopSpan.class);
+ if (spans.length > 0) {
+ int[] stops = new int[spans.length];
+ for (int i = 0; i < spans.length; i++) {
+ stops[i] = spans[i].getTabStop();
}
-
- boolean isSpaceOrTab = c == CHAR_SPACE || c == CHAR_TAB || c == CHAR_ZWSP;
-
- if (w <= width || isSpaceOrTab) {
- fitWidth = w;
- if (!isSpaceOrTab) {
- fitWidthGraphing = w;
- }
- fit = j + 1;
-
- if (fmTop < fitTop)
- fitTop = fmTop;
- if (fmAscent < fitAscent)
- fitAscent = fmAscent;
- if (fmDescent > fitDescent)
- fitDescent = fmDescent;
- if (fmBottom > fitBottom)
- fitBottom = fmBottom;
-
- while (breakOpp[breakOppIndex] != -1
- && breakOpp[breakOppIndex] < j - paraStart + 1) {
- breakOppIndex++;
- }
- boolean isLineBreak = breakOppIndex < breakOpp.length &&
- breakOpp[breakOppIndex] == j - paraStart + 1;
-
- if (isLineBreak) {
- okWidth = fitWidthGraphing;
- ok = j + 1;
-
- if (fitTop < okTop)
- okTop = fitTop;
- if (fitAscent < okAscent)
- okAscent = fitAscent;
- if (fitDescent > okDescent)
- okDescent = fitDescent;
- if (fitBottom > okBottom)
- okBottom = fitBottom;
- }
- } else {
- final boolean moreChars;
- int endPos;
- int above, below, top, bottom;
- float currentTextWidth;
-
- if (ok != here) {
- endPos = ok;
- above = okAscent;
- below = okDescent;
- top = okTop;
- bottom = okBottom;
- currentTextWidth = okWidth;
- moreChars = (j + 1 < spanEnd);
- } else if (fit != here) {
- endPos = fit;
- above = fitAscent;
- below = fitDescent;
- top = fitTop;
- bottom = fitBottom;
- currentTextWidth = fitWidth;
- moreChars = (j + 1 < spanEnd);
- } else {
- // must make progress, so take next character
- endPos = here + 1;
- // but to deal properly with clusters
- // take all zero width characters following that
- while (endPos < spanEnd && widths[endPos - paraStart] == 0) {
- endPos++;
- }
- above = fmAscent;
- below = fmDescent;
- top = fmTop;
- bottom = fmBottom;
- currentTextWidth = widths[here - paraStart];
- moreChars = (endPos < spanEnd);
- }
-
- v = out(source, here, endPos,
- above, below, top, bottom,
- v, spacingmult, spacingadd, chooseHt,chooseHtv, fm, hasTabOrEmoji,
- needMultiply, chdirs, dir, easy, bufEnd, includepad, trackpad,
- chs, widths, paraStart, ellipsize, ellipsizedWidth,
- currentTextWidth, paint, moreChars);
-
- here = endPos;
- j = here - 1; // restart j-span loop from here, compensating for the j++
- ok = fit = here;
- w = 0;
- fitWidthGraphing = w;
- fitAscent = fitDescent = fitTop = fitBottom = 0;
- okAscent = okDescent = okTop = okBottom = 0;
-
- if (--firstWidthLineLimit <= 0) {
- width = restWidth;
- }
-
- if (here < spanStart) {
- // The text was cut before the beginning of the current span range.
- // Exit the span loop, and get spanStart to start over from here.
- measured.setPos(here);
- spanEnd = here;
- break;
- }
-
- if (mLineCount >= mMaximumVisibleLineCount) {
- return;
- }
- }
+ Arrays.sort(stops, 0, stops.length);
+ variableTabStops = stops;
}
}
- if (paraEnd != here && mLineCount < mMaximumVisibleLineCount) {
- if ((fitTop | fitBottom | fitDescent | fitAscent) == 0) {
- paint.getFontMetricsInt(fm);
+ int breakCount = nComputeLineBreaks(localeLanguageTag, chs, widths, paraEnd - paraStart, firstWidth,
+ firstWidthLineCount, restWidth, variableTabStops, TAB_INCREMENT, false, lineBreaks,
+ lineBreaks.breaks, lineBreaks.widths, lineBreaks.flags, lineBreaks.breaks.length);
- fitTop = fm.top;
- fitBottom = fm.bottom;
- fitAscent = fm.ascent;
- fitDescent = fm.descent;
+ int[] breaks = lineBreaks.breaks;
+ float[] lineWidths = lineBreaks.widths;
+ boolean[] flags = lineBreaks.flags;
+
+
+ // here is the offset of the starting character of the line we are currently measuring
+ int here = paraStart;
+
+ int fmTop = 0, fmBottom = 0, fmAscent = 0, fmDescent = 0;
+ int fmCacheIndex = 0;
+ int spanEndCacheIndex = 0;
+ int breakIndex = 0;
+ for (int spanStart = paraStart, spanEnd; spanStart < paraEnd; spanStart = spanEnd) {
+ // retrieve end of span
+ spanEnd = spanEndCache[spanEndCacheIndex++];
+
+ // retrieve cached metrics, order matches above
+ fm.top = fmCache[fmCacheIndex * 4 + 0];
+ fm.bottom = fmCache[fmCacheIndex * 4 + 1];
+ fm.ascent = fmCache[fmCacheIndex * 4 + 2];
+ fm.descent = fmCache[fmCacheIndex * 4 + 3];
+ fmCacheIndex++;
+
+ if (fm.top < fmTop) {
+ fmTop = fm.top;
+ }
+ if (fm.ascent < fmAscent) {
+ fmAscent = fm.ascent;
+ }
+ if (fm.descent > fmDescent) {
+ fmDescent = fm.descent;
+ }
+ if (fm.bottom > fmBottom) {
+ fmBottom = fm.bottom;
}
- // Log.e("text", "output rest " + here + " to " + end);
+ // skip breaks ending before current span range
+ while (breakIndex < breakCount && paraStart + breaks[breakIndex] < spanStart) {
+ breakIndex++;
+ }
- v = out(source,
- here, paraEnd, fitAscent, fitDescent,
- fitTop, fitBottom,
- v,
- spacingmult, spacingadd, chooseHt,
- chooseHtv, fm, hasTabOrEmoji,
- needMultiply, chdirs, dir, easy, bufEnd,
- includepad, trackpad, chs,
- widths, paraStart, ellipsize,
- ellipsizedWidth, w, paint, paraEnd != bufEnd);
+ while (breakIndex < breakCount && paraStart + breaks[breakIndex] <= spanEnd) {
+ int endPos = paraStart + breaks[breakIndex];
+
+ boolean moreChars = (endPos < paraEnd); // XXX is this the right way to calculate this?
+
+ v = out(source, here, endPos,
+ fmAscent, fmDescent, fmTop, fmBottom,
+ v, spacingmult, spacingadd, chooseHt,chooseHtv, fm, flags[breakIndex],
+ needMultiply, chdirs, dir, easy, bufEnd, includepad, trackpad,
+ chs, widths, paraStart, ellipsize, ellipsizedWidth,
+ lineWidths[breakIndex], paint, moreChars);
+
+ if (endPos < spanEnd) {
+ // preserve metrics for current span
+ fmTop = fm.top;
+ fmBottom = fm.bottom;
+ fmAscent = fm.ascent;
+ fmDescent = fm.descent;
+ } else {
+ fmTop = fmBottom = fmAscent = fmDescent = 0;
+ }
+
+ here = endPos;
+ breakIndex++;
+
+ if (mLineCount >= mMaximumVisibleLineCount) {
+ return;
+ }
+ }
}
- paraStart = paraEnd;
-
if (paraEnd == bufEnd)
break;
}
@@ -488,7 +391,7 @@
mLineCount < mMaximumVisibleLineCount) {
// Log.e("text", "output last " + bufEnd);
- measured.setPara(source, bufStart, bufEnd, textDir);
+ measured.setPara(source, bufEnd, bufEnd, textDir);
paint.getFontMetricsInt(fm);
@@ -848,15 +751,20 @@
void prepare() {
mMeasured = MeasuredText.obtain();
}
-
+
void finish() {
mMeasured = MeasuredText.recycle(mMeasured);
}
- // returns an array with terminal sentinel value -1 to indicate end
- // this is so that arrays can be recycled instead of allocating new arrays
- // every time
- private static native int[] nLineBreakOpportunities(String locale, char[] text, int length, int[] recycle);
+ // populates LineBreaks and returns the number of breaks found
+ //
+ // the arrays inside the LineBreaks objects are passed in as well
+ // to reduce the number of JNI calls in the common case where the
+ // arrays do not have to be resized
+ private static native int nComputeLineBreaks(String locale, char[] text, float[] widths,
+ int length, float firstWidth, int firstWidthLineCount, float restWidth,
+ int[] variableTabStops, int defaultTabStop, boolean optimize, LineBreaks recycle,
+ int[] recycleBreaks, float[] recycleWidths, boolean[] recycleFlags, int recycleLength);
private int mLineCount;
private int mTopPadding, mBottomPadding;
@@ -884,18 +792,23 @@
private static final int TAB_INCREMENT = 20; // same as Layout, but that's private
private static final char CHAR_NEW_LINE = '\n';
- private static final char CHAR_TAB = '\t';
- private static final char CHAR_SPACE = ' ';
- private static final char CHAR_ZWSP = '\u200B';
private static final double EXTRA_ROUNDING = 0.5;
- private static final int CHAR_FIRST_HIGH_SURROGATE = 0xD800;
- private static final int CHAR_LAST_LOW_SURROGATE = 0xDFFF;
-
/*
* This is reused across calls to generate()
*/
private MeasuredText mMeasured;
private Paint.FontMetricsInt mFontMetricsInt = new Paint.FontMetricsInt();
+
+ // This is used to return three arrays from a single JNI call when
+ // performing line breaking
+ /*package*/ static class LineBreaks {
+ private static final int INITIAL_SIZE = 16;
+ public int[] breaks = new int[INITIAL_SIZE];
+ public float[] widths = new float[INITIAL_SIZE];
+ public boolean[] flags = new boolean[INITIAL_SIZE]; // hasTabOrEmoji
+ // breaks, widths, and flags should all have the same length
+ }
+
}
diff --git a/core/java/android/text/TextUtils.java b/core/java/android/text/TextUtils.java
index 3502b52..8a8c6d8 100644
--- a/core/java/android/text/TextUtils.java
+++ b/core/java/android/text/TextUtils.java
@@ -63,6 +63,8 @@
public class TextUtils {
private static final String TAG = "TextUtils";
+ private static final String ELLIPSIS = new String(Layout.ELLIPSIS_NORMAL);
+ private static final String ELLIPSIS_TWO_DOTS = new String(Layout.ELLIPSIS_TWO_DOTS);
private TextUtils() { /* cannot be instantiated */ }
@@ -1081,14 +1083,9 @@
float avail, TruncateAt where,
boolean preserveLength,
EllipsizeCallback callback) {
-
- final String ellipsis = (where == TruncateAt.END_SMALL) ?
- Resources.getSystem().getString(R.string.ellipsis_two_dots) :
- Resources.getSystem().getString(R.string.ellipsis);
-
return ellipsize(text, paint, avail, where, preserveLength, callback,
TextDirectionHeuristics.FIRSTSTRONG_LTR,
- ellipsis);
+ (where == TruncateAt.END_SMALL) ? ELLIPSIS_TWO_DOTS : ELLIPSIS);
}
/**
diff --git a/core/java/android/text/format/DateFormat.java b/core/java/android/text/format/DateFormat.java
index 933bcee..afeb24e6 100755
--- a/core/java/android/text/format/DateFormat.java
+++ b/core/java/android/text/format/DateFormat.java
@@ -254,7 +254,7 @@
*/
public static String getTimeFormatString(Context context) {
LocaleData d = LocaleData.get(context.getResources().getConfiguration().locale);
- return is24HourFormat(context) ? d.timeFormat24 : d.timeFormat12;
+ return is24HourFormat(context) ? d.timeFormat_Hm : d.timeFormat_hm;
}
/**
diff --git a/core/java/android/text/format/Time.java b/core/java/android/text/format/Time.java
index 1e04eb4..0c66709 100644
--- a/core/java/android/text/format/Time.java
+++ b/core/java/android/text/format/Time.java
@@ -215,13 +215,15 @@
* <p>
* If "ignoreDst" is true, then this method sets the "isDst" field to -1
* (the "unknown" value) before normalizing. It then computes the
- * correct value for "isDst".
+ * time in milliseconds and sets the correct value for "isDst" if the
+ * fields resolve to a valid date / time.
*
* <p>
* See {@link #toMillis(boolean)} for more information about when to
- * use <tt>true</tt> or <tt>false</tt> for "ignoreDst".
+ * use <tt>true</tt> or <tt>false</tt> for "ignoreDst" and when {@code -1}
+ * might be returned.
*
- * @return the UTC milliseconds since the epoch
+ * @return the UTC milliseconds since the epoch, or {@code -1}
*/
public long normalize(boolean ignoreDst) {
calculator.copyFieldsFromTime(this);
@@ -317,6 +319,11 @@
* a} is less than {@code b}, a positive number if {@code a} is greater than
* {@code b}, or 0 if they are equal.
*
+ * <p>
+ * This method can return an incorrect answer when the date / time fields of
+ * either {@code Time} have been set to a local time that contradicts the
+ * available timezone information.
+ *
* @param a first {@code Time} instance to compare
* @param b second {@code Time} instance to compare
* @throws NullPointerException if either argument is {@code null}
@@ -730,6 +737,14 @@
* <p>
* You should also use <tt>toMillis(false)</tt> if you want
* to read back the same milliseconds that you set with {@link #set(long)}
+ *
+ * <p>
+ * This method can return {@code -1} when the date / time fields have been
+ * set to a local time that conflicts with available timezone information.
+ * For example, when daylight savings transitions cause an hour to be
+ * skipped: times within that hour will return {@code -1} if isDst =
+ * {@code -1}.
+ *
* or {@link #set(Time)} or after parsing a date string.
*/
public long toMillis(boolean ignoreDst) {
@@ -825,6 +840,10 @@
* Returns true if the time represented by this Time object occurs before
* the given time.
*
+ * <p>
+ * Equivalent to {@code Time.compare(this, that) < 0}. See
+ * {@link #compare(Time, Time)} for details.
+ *
* @param that a given Time object to compare against
* @return true if this time is less than the given time
*/
@@ -837,6 +856,10 @@
* Returns true if the time represented by this Time object occurs after
* the given time.
*
+ * <p>
+ * Equivalent to {@code Time.compare(this, that) > 0}. See
+ * {@link #compare(Time, Time)} for details.
+ *
* @param that a given Time object to compare against
* @return true if this time is greater than the given time
*/
@@ -917,6 +940,10 @@
* Returns true if the day of the given time is the epoch on the Julian Calendar
* (January 1, 1970 on the Gregorian calendar).
*
+ * <p>
+ * This method can return an incorrect answer when the date / time fields have
+ * been set to a local time that contradicts the available timezone information.
+ *
* @param time the time to test
* @return true if epoch.
*/
diff --git a/core/java/android/util/FloatMath.java b/core/java/android/util/FloatMath.java
index bdcf5ca..8f488af 100644
--- a/core/java/android/util/FloatMath.java
+++ b/core/java/android/util/FloatMath.java
@@ -17,10 +17,13 @@
package android.util;
/**
- * Math routines similar to those found in {@link java.lang.Math}. On
- * versions of Android with a JIT, these are significantly slower than
- * the equivalent {@code Math} functions, which should be used in preference
- * to these.
+ * Math routines similar to those found in {@link java.lang.Math}.
+ *
+ * <p>Historically these methods were faster than the equivalent double-based
+ * {@link java.lang.Math} methods. On versions of Android with a JIT they
+ * became slower and have since been re-implemented to wrap calls to
+ * {@link java.lang.Math}. {@link java.lang.Math} should be used in
+ * preference.
*
* @deprecated Use {@link java.lang.Math} instead.
*/
@@ -37,7 +40,9 @@
* @param value to be converted
* @return the floor of value
*/
- public static native float floor(float value);
+ public static float floor(float value) {
+ return (float) Math.floor(value);
+ }
/**
* Returns the float conversion of the most negative (i.e. closest to
@@ -46,7 +51,9 @@
* @param value to be converted
* @return the ceiling of value
*/
- public static native float ceil(float value);
+ public static float ceil(float value) {
+ return (float) Math.ceil(value);
+ }
/**
* Returns the closest float approximation of the sine of the argument.
@@ -54,7 +61,9 @@
* @param angle to compute the cosine of, in radians
* @return the sine of angle
*/
- public static native float sin(float angle);
+ public static float sin(float angle) {
+ return (float) Math.sin(angle);
+ }
/**
* Returns the closest float approximation of the cosine of the argument.
@@ -62,7 +71,9 @@
* @param angle to compute the cosine of, in radians
* @return the cosine of angle
*/
- public static native float cos(float angle);
+ public static float cos(float angle) {
+ return (float) Math.cos(angle);
+ }
/**
* Returns the closest float approximation of the square root of the
@@ -71,7 +82,9 @@
* @param value to compute sqrt of
* @return the square root of value
*/
- public static native float sqrt(float value);
+ public static float sqrt(float value) {
+ return (float) Math.sqrt(value);
+ }
/**
* Returns the closest float approximation of the raising "e" to the power
@@ -80,7 +93,9 @@
* @param value to compute the exponential of
* @return the exponential of value
*/
- public static native float exp(float value);
+ public static float exp(float value) {
+ return (float) Math.exp(value);
+ }
/**
* Returns the closest float approximation of the result of raising {@code
@@ -90,7 +105,9 @@
* @param y the exponent of the operation.
* @return {@code x} to the power of {@code y}.
*/
- public static native float pow(float x, float y);
+ public static float pow(float x, float y) {
+ return (float) Math.pow(x, y);
+ }
/**
* Returns {@code sqrt(}<i>{@code x}</i><sup>{@code 2}</sup>{@code +} <i>
@@ -100,5 +117,7 @@
* @param y a float number
* @return the hypotenuse
*/
- public static native float hypot(float x, float y);
+ public static float hypot(float x, float y) {
+ return (float) Math.hypot(x, y);
+ }
}
diff --git a/core/java/android/util/MathUtils.java b/core/java/android/util/MathUtils.java
index 13a692e..36d5b50 100644
--- a/core/java/android/util/MathUtils.java
+++ b/core/java/android/util/MathUtils.java
@@ -94,7 +94,7 @@
public static float dist(float x1, float y1, float x2, float y2) {
final float x = (x2 - x1);
final float y = (y2 - y1);
- return (float) Math.sqrt(x * x + y * y);
+ return (float) Math.hypot(x, y);
}
public static float dist(float x1, float y1, float z1, float x2, float y2, float z2) {
@@ -105,7 +105,7 @@
}
public static float mag(float a, float b) {
- return (float) Math.sqrt(a * a + b * b);
+ return (float) Math.hypot(a, b);
}
public static float mag(float a, float b, float c) {
diff --git a/core/java/android/util/Spline.java b/core/java/android/util/Spline.java
index 41a2e5d..bed3a60 100644
--- a/core/java/android/util/Spline.java
+++ b/core/java/android/util/Spline.java
@@ -165,7 +165,7 @@
throw new IllegalArgumentException("The control points must have "
+ "monotonic Y values.");
}
- float h = FloatMath.hypot(a, b);
+ float h = (float) Math.hypot(a, b);
if (h > 9f) {
float t = 3f / h;
m[i] = t * a * d[i];
diff --git a/core/java/android/view/GLES20Canvas.java b/core/java/android/view/GLES20Canvas.java
index b86455a..41a4a7c 100644
--- a/core/java/android/view/GLES20Canvas.java
+++ b/core/java/android/view/GLES20Canvas.java
@@ -191,17 +191,17 @@
private static native void nInsertReorderBarrier(long renderer, boolean enableReorder);
@Override
- public int onPreDraw(Rect dirty) {
+ public void onPreDraw(Rect dirty) {
if (dirty != null) {
- return nPrepareDirty(mRenderer, dirty.left, dirty.top, dirty.right, dirty.bottom,
+ nPrepareDirty(mRenderer, dirty.left, dirty.top, dirty.right, dirty.bottom,
mOpaque);
} else {
- return nPrepare(mRenderer, mOpaque);
+ nPrepare(mRenderer, mOpaque);
}
}
- private static native int nPrepare(long renderer, boolean opaque);
- private static native int nPrepareDirty(long renderer, int left, int top, int right, int bottom,
+ private static native void nPrepare(long renderer, boolean opaque);
+ private static native void nPrepareDirty(long renderer, int left, int top, int right, int bottom,
boolean opaque);
@Override
@@ -216,11 +216,11 @@
///////////////////////////////////////////////////////////////////////////
@Override
- public int callDrawGLFunction(long drawGLFunction) {
- return nCallDrawGLFunction(mRenderer, drawGLFunction);
+ public void callDrawGLFunction(long drawGLFunction) {
+ nCallDrawGLFunction(mRenderer, drawGLFunction);
}
- private static native int nCallDrawGLFunction(long renderer, long drawGLFunction);
+ private static native void nCallDrawGLFunction(long renderer, long drawGLFunction);
///////////////////////////////////////////////////////////////////////////
// Display list
@@ -229,12 +229,12 @@
protected static native long nFinishRecording(long renderer);
@Override
- public int drawRenderNode(RenderNode renderNode, Rect dirty, int flags) {
- return nDrawRenderNode(mRenderer, renderNode.getNativeDisplayList(), dirty, flags);
+ public void drawRenderNode(RenderNode renderNode, int flags) {
+ nDrawRenderNode(mRenderer, renderNode.getNativeDisplayList(), flags);
}
- private static native int nDrawRenderNode(long renderer, long renderNode,
- Rect dirty, int flags);
+ private static native void nDrawRenderNode(long renderer, long renderNode,
+ int flags);
///////////////////////////////////////////////////////////////////////////
// Hardware layer
@@ -447,7 +447,7 @@
return saveLayer(bounds.left, bounds.top, bounds.right, bounds.bottom, paint, saveFlags);
}
- final long nativePaint = paint == null ? 0 : paint.mNativePaint;
+ final long nativePaint = paint == null ? 0 : paint.getNativeInstance();
return nSaveLayer(mRenderer, nativePaint, saveFlags);
}
@@ -457,7 +457,7 @@
public int saveLayer(float left, float top, float right, float bottom, Paint paint,
int saveFlags) {
if (left < right && top < bottom) {
- final long nativePaint = paint == null ? 0 : paint.mNativePaint;
+ final long nativePaint = paint == null ? 0 : paint.getNativeInstance();
return nSaveLayer(mRenderer, left, top, right, bottom, nativePaint, saveFlags);
}
return save(saveFlags);
@@ -517,16 +517,10 @@
@Override
public void setDrawFilter(DrawFilter filter) {
mFilter = filter;
- if (filter == null) {
- nResetPaintFilter(mRenderer);
- } else if (filter instanceof PaintFlagsDrawFilter) {
- PaintFlagsDrawFilter flagsFilter = (PaintFlagsDrawFilter) filter;
- nSetupPaintFilter(mRenderer, flagsFilter.clearBits, flagsFilter.setBits);
- }
+ nSetDrawFilter(mRenderer, (filter != null) ? filter.mNativeInt : 0);
}
- private static native void nResetPaintFilter(long renderer);
- private static native void nSetupPaintFilter(long renderer, int clearBits, int setBits);
+ private static native void nSetDrawFilter(long renderer, long nativeFilter);
@Override
public DrawFilter getDrawFilter() {
@@ -541,7 +535,7 @@
public void drawArc(float left, float top, float right, float bottom,
float startAngle, float sweepAngle, boolean useCenter, Paint paint) {
nDrawArc(mRenderer, left, top, right, bottom,
- startAngle, sweepAngle, useCenter, paint.mNativePaint);
+ startAngle, sweepAngle, useCenter, paint.getNativeInstance());
}
private static native void nDrawArc(long renderer, float left, float top,
@@ -557,7 +551,7 @@
public void drawPatch(NinePatch patch, Rect dst, Paint paint) {
Bitmap bitmap = patch.getBitmap();
throwIfCannotDraw(bitmap);
- final long nativePaint = paint == null ? 0 : paint.mNativePaint;
+ final long nativePaint = paint == null ? 0 : paint.getNativeInstance();
nDrawPatch(mRenderer, bitmap.mNativeBitmap, bitmap.mBuffer, patch.mNativeChunk,
dst.left, dst.top, dst.right, dst.bottom, nativePaint);
}
@@ -566,7 +560,7 @@
public void drawPatch(NinePatch patch, RectF dst, Paint paint) {
Bitmap bitmap = patch.getBitmap();
throwIfCannotDraw(bitmap);
- final long nativePaint = paint == null ? 0 : paint.mNativePaint;
+ final long nativePaint = paint == null ? 0 : paint.getNativeInstance();
nDrawPatch(mRenderer, bitmap.mNativeBitmap, bitmap.mBuffer, patch.mNativeChunk,
dst.left, dst.top, dst.right, dst.bottom, nativePaint);
}
@@ -577,7 +571,7 @@
@Override
public void drawBitmap(Bitmap bitmap, float left, float top, Paint paint) {
throwIfCannotDraw(bitmap);
- final long nativePaint = paint == null ? 0 : paint.mNativePaint;
+ final long nativePaint = paint == null ? 0 : paint.getNativeInstance();
nDrawBitmap(mRenderer, bitmap.mNativeBitmap, bitmap.mBuffer, left, top, nativePaint);
}
@@ -587,7 +581,7 @@
@Override
public void drawBitmap(Bitmap bitmap, Matrix matrix, Paint paint) {
throwIfCannotDraw(bitmap);
- final long nativePaint = paint == null ? 0 : paint.mNativePaint;
+ final long nativePaint = paint == null ? 0 : paint.getNativeInstance();
nDrawBitmap(mRenderer, bitmap.mNativeBitmap, bitmap.mBuffer,
matrix.native_instance, nativePaint);
}
@@ -598,7 +592,7 @@
@Override
public void drawBitmap(Bitmap bitmap, Rect src, Rect dst, Paint paint) {
throwIfCannotDraw(bitmap);
- final long nativePaint = paint == null ? 0 : paint.mNativePaint;
+ final long nativePaint = paint == null ? 0 : paint.getNativeInstance();
int left, top, right, bottom;
if (src == null) {
@@ -619,7 +613,7 @@
@Override
public void drawBitmap(Bitmap bitmap, Rect src, RectF dst, Paint paint) {
throwIfCannotDraw(bitmap);
- final long nativePaint = paint == null ? 0 : paint.mNativePaint;
+ final long nativePaint = paint == null ? 0 : paint.getNativeInstance();
float left, top, right, bottom;
if (src == null) {
@@ -664,7 +658,7 @@
throw new ArrayIndexOutOfBoundsException();
}
- final long nativePaint = paint == null ? 0 : paint.mNativePaint;
+ final long nativePaint = paint == null ? 0 : paint.getNativeInstance();
nDrawBitmap(mRenderer, colors, offset, stride, x, y,
width, height, hasAlpha, nativePaint);
}
@@ -697,7 +691,7 @@
checkRange(colors.length, colorOffset, count);
}
- final long nativePaint = paint == null ? 0 : paint.mNativePaint;
+ final long nativePaint = paint == null ? 0 : paint.getNativeInstance();
nDrawBitmapMesh(mRenderer, bitmap.mNativeBitmap, bitmap.mBuffer, meshWidth, meshHeight,
verts, vertOffset, colors, colorOffset, nativePaint);
}
@@ -708,7 +702,7 @@
@Override
public void drawCircle(float cx, float cy, float radius, Paint paint) {
- nDrawCircle(mRenderer, cx, cy, radius, paint.mNativePaint);
+ nDrawCircle(mRenderer, cx, cy, radius, paint.getNativeInstance());
}
private static native void nDrawCircle(long renderer, float cx, float cy,
@@ -766,7 +760,7 @@
if ((offset | count) < 0 || offset + count > pts.length) {
throw new IllegalArgumentException("The lines array must contain 4 elements per line.");
}
- nDrawLines(mRenderer, pts, offset, count, paint.mNativePaint);
+ nDrawLines(mRenderer, pts, offset, count, paint.getNativeInstance());
}
private static native void nDrawLines(long renderer, float[] points,
@@ -779,7 +773,7 @@
@Override
public void drawOval(float left, float top, float right, float bottom, Paint paint) {
- nDrawOval(mRenderer, left, top, right, bottom, paint.mNativePaint);
+ nDrawOval(mRenderer, left, top, right, bottom, paint.getNativeInstance());
}
private static native void nDrawOval(long renderer, float left, float top,
@@ -796,10 +790,10 @@
public void drawPath(Path path, Paint paint) {
if (path.isSimplePath) {
if (path.rects != null) {
- nDrawRects(mRenderer, path.rects.mNativeRegion, paint.mNativePaint);
+ nDrawRects(mRenderer, path.rects.mNativeRegion, paint.getNativeInstance());
}
} else {
- nDrawPath(mRenderer, path.mNativePath, paint.mNativePaint);
+ nDrawPath(mRenderer, path.mNativePath, paint.getNativeInstance());
}
}
@@ -829,7 +823,7 @@
public void drawPoints(float[] pts, int offset, int count, Paint paint) {
if (count < 2) return;
- nDrawPoints(mRenderer, pts, offset, count, paint.mNativePaint);
+ nDrawPoints(mRenderer, pts, offset, count, paint.getNativeInstance());
}
private static native void nDrawPoints(long renderer, float[] points,
@@ -840,7 +834,7 @@
@Override
public void drawRect(float left, float top, float right, float bottom, Paint paint) {
if (left == right || top == bottom) return;
- nDrawRect(mRenderer, left, top, right, bottom, paint.mNativePaint);
+ nDrawRect(mRenderer, left, top, right, bottom, paint.getNativeInstance());
}
private static native void nDrawRect(long renderer, float left, float top,
@@ -864,7 +858,7 @@
@Override
public void drawRoundRect(float left, float top, float right, float bottom, float rx, float ry,
Paint paint) {
- nDrawRoundRect(mRenderer, left, top, right, bottom, rx, ry, paint.mNativePaint);
+ nDrawRoundRect(mRenderer, left, top, right, bottom, rx, ry, paint.getNativeInstance());
}
private static native void nDrawRoundRect(long renderer, float left, float top,
@@ -877,7 +871,7 @@
}
nDrawText(mRenderer, text, index, count, x, y,
- paint.mBidiFlags, paint.mNativePaint, paint.mNativeTypeface);
+ paint.mBidiFlags, paint.getNativeInstance(), paint.mNativeTypeface);
}
private static native void nDrawText(long renderer, char[] text, int index, int count,
@@ -888,14 +882,14 @@
if (text instanceof String || text instanceof SpannedString ||
text instanceof SpannableString) {
nDrawText(mRenderer, text.toString(), start, end, x, y, paint.mBidiFlags,
- paint.mNativePaint, paint.mNativeTypeface);
+ paint.getNativeInstance(), paint.mNativeTypeface);
} else if (text instanceof GraphicsOperations) {
((GraphicsOperations) text).drawText(this, start, end, x, y, paint);
} else {
char[] buf = TemporaryBuffer.obtain(end - start);
TextUtils.getChars(text, start, end, buf, 0);
nDrawText(mRenderer, buf, 0, end - start, x, y,
- paint.mBidiFlags, paint.mNativePaint, paint.mNativeTypeface);
+ paint.mBidiFlags, paint.getNativeInstance(), paint.mNativeTypeface);
TemporaryBuffer.recycle(buf);
}
}
@@ -907,7 +901,7 @@
}
nDrawText(mRenderer, text, start, end, x, y,
- paint.mBidiFlags, paint.mNativePaint, paint.mNativeTypeface);
+ paint.mBidiFlags, paint.getNativeInstance(), paint.mNativeTypeface);
}
private static native void nDrawText(long renderer, String text, int start, int end,
@@ -916,7 +910,7 @@
@Override
public void drawText(String text, float x, float y, Paint paint) {
nDrawText(mRenderer, text, 0, text.length(), x, y,
- paint.mBidiFlags, paint.mNativePaint, paint.mNativeTypeface);
+ paint.mBidiFlags, paint.getNativeInstance(), paint.mNativeTypeface);
}
@Override
@@ -927,7 +921,7 @@
}
nDrawTextOnPath(mRenderer, text, index, count, path.mNativePath, hOffset, vOffset,
- paint.mBidiFlags, paint.mNativePaint, paint.mNativeTypeface);
+ paint.mBidiFlags, paint.getNativeInstance(), paint.mNativeTypeface);
}
private static native void nDrawTextOnPath(long renderer, char[] text, int index, int count,
@@ -939,7 +933,7 @@
if (text.length() == 0) return;
nDrawTextOnPath(mRenderer, text, 0, text.length(), path.mNativePath, hOffset, vOffset,
- paint.mBidiFlags, paint.mNativePaint, paint.mNativeTypeface);
+ paint.mBidiFlags, paint.getNativeInstance(), paint.mNativeTypeface);
}
private static native void nDrawTextOnPath(long renderer, String text, int start, int end,
@@ -954,7 +948,7 @@
}
nDrawTextRun(mRenderer, text, index, count, contextIndex, contextCount, x, y, isRtl,
- paint.mNativePaint, paint.mNativeTypeface);
+ paint.getNativeInstance(), paint.mNativeTypeface);
}
private static native void nDrawTextRun(long renderer, char[] text, int index, int count,
@@ -970,7 +964,7 @@
if (text instanceof String || text instanceof SpannedString ||
text instanceof SpannableString) {
nDrawTextRun(mRenderer, text.toString(), start, end, contextStart,
- contextEnd, x, y, isRtl, paint.mNativePaint, paint.mNativeTypeface);
+ contextEnd, x, y, isRtl, paint.getNativeInstance(), paint.mNativeTypeface);
} else if (text instanceof GraphicsOperations) {
((GraphicsOperations) text).drawTextRun(this, start, end,
contextStart, contextEnd, x, y, isRtl, paint);
@@ -980,7 +974,7 @@
char[] buf = TemporaryBuffer.obtain(contextLen);
TextUtils.getChars(text, contextStart, contextEnd, buf, 0);
nDrawTextRun(mRenderer, buf, start - contextStart, len, 0, contextLen,
- x, y, isRtl, paint.mNativePaint, paint.mNativeTypeface);
+ x, y, isRtl, paint.getNativeInstance(), paint.mNativeTypeface);
TemporaryBuffer.recycle(buf);
}
}
diff --git a/core/java/android/view/HardwareCanvas.java b/core/java/android/view/HardwareCanvas.java
index e3eee71..4e30749 100644
--- a/core/java/android/view/HardwareCanvas.java
+++ b/core/java/android/view/HardwareCanvas.java
@@ -43,12 +43,10 @@
* Invoked before any drawing operation is performed in this canvas.
*
* @param dirty The dirty rectangle to update, can be null.
- * @return {@link RenderNode#STATUS_DREW} if anything was drawn (such as a call to clear
- * the canvas).
*
* @hide
*/
- public abstract int onPreDraw(Rect dirty);
+ public abstract void onPreDraw(Rect dirty);
/**
* Invoked after all drawing operation have been performed.
@@ -64,7 +62,7 @@
* @param renderNode The RenderNode to replay.
*/
public void drawRenderNode(RenderNode renderNode) {
- drawRenderNode(renderNode, null, RenderNode.FLAG_CLIP_CHILDREN);
+ drawRenderNode(renderNode, RenderNode.FLAG_CLIP_CHILDREN);
}
/**
@@ -75,12 +73,9 @@
* @param flags Optional flags about drawing, see {@link RenderNode} for
* the possible flags.
*
- * @return One of {@link RenderNode#STATUS_DONE} or {@link RenderNode#STATUS_DREW}
- * if anything was drawn.
- *
* @hide
*/
- public abstract int drawRenderNode(RenderNode renderNode, Rect dirty, int flags);
+ public abstract void drawRenderNode(RenderNode renderNode, int flags);
/**
* Draws the specified layer onto this canvas.
@@ -101,13 +96,10 @@
*
* @param drawGLFunction A native function pointer
*
- * @return {@link RenderNode#STATUS_DONE}
- *
* @hide
*/
- public int callDrawGLFunction(long drawGLFunction) {
+ public void callDrawGLFunction(long drawGLFunction) {
// Noop - this is done in the display list recorder subclass
- return RenderNode.STATUS_DONE;
}
public abstract void drawCircle(CanvasProperty<Float> cx, CanvasProperty<Float> cy,
diff --git a/core/java/android/view/HardwareLayer.java b/core/java/android/view/HardwareLayer.java
index a130bda..65ae8a6 100644
--- a/core/java/android/view/HardwareLayer.java
+++ b/core/java/android/view/HardwareLayer.java
@@ -52,7 +52,7 @@
* @see View#setLayerPaint(android.graphics.Paint)
*/
public void setLayerPaint(Paint paint) {
- nSetLayerPaint(mFinalizer.get(), paint.mNativePaint);
+ nSetLayerPaint(mFinalizer.get(), paint.getNativeInstance());
mRenderer.pushLayerUpdate(this);
}
diff --git a/core/java/android/view/RenderNode.java b/core/java/android/view/RenderNode.java
index 47f72a8..09eb486 100644
--- a/core/java/android/view/RenderNode.java
+++ b/core/java/android/view/RenderNode.java
@@ -305,7 +305,7 @@
}
public boolean setLayerPaint(Paint paint) {
- return nSetLayerPaint(mNativeRenderNode, paint != null ? paint.mNativePaint : 0);
+ return nSetLayerPaint(mNativeRenderNode, paint != null ? paint.getNativeInstance() : 0);
}
public boolean setClipBounds(@Nullable Rect rect) {
diff --git a/core/java/android/view/ScaleGestureDetector.java b/core/java/android/view/ScaleGestureDetector.java
index 42a58a8..6508cca 100644
--- a/core/java/android/view/ScaleGestureDetector.java
+++ b/core/java/android/view/ScaleGestureDetector.java
@@ -21,7 +21,6 @@
import android.os.Build;
import android.os.Handler;
import android.os.SystemClock;
-import android.util.FloatMath;
/**
* Detects scaling transformation gestures using the supplied {@link MotionEvent}s.
@@ -394,7 +393,7 @@
if (inDoubleTapMode()) {
span = spanY;
} else {
- span = FloatMath.sqrt(spanX * spanX + spanY * spanY);
+ span = (float) Math.hypot(spanX, spanY);
}
// Dispatch begin/end events as needed.
diff --git a/core/java/android/view/Surface.java b/core/java/android/view/Surface.java
index 19142b8..82ef171 100644
--- a/core/java/android/view/Surface.java
+++ b/core/java/android/view/Surface.java
@@ -319,7 +319,6 @@
* @return A canvas for drawing into the surface.
*
* @throws IllegalStateException If the canvas cannot be locked.
- * @hide
*/
public Canvas lockHardwareCanvas() {
synchronized (mLock) {
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 1d09696..069f5d2 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -15202,7 +15202,7 @@
}
} else {
mPrivateFlags &= ~PFLAG_DIRTY_MASK;
- ((HardwareCanvas) canvas).drawRenderNode(renderNode, null, flags);
+ ((HardwareCanvas) canvas).drawRenderNode(renderNode, flags);
}
}
} else if (cache != null) {
@@ -17317,7 +17317,7 @@
*
* The specified key should be an id declared in the resources of the
* application to ensure it is unique (see the <a
- * href={@docRoot}guide/topics/resources/more-resources.html#Id">ID resource type</a>).
+ * href="{@docRoot}guide/topics/resources/more-resources.html#Id">ID resource type</a>).
* Keys identified as belonging to
* the Android framework or not associated with any package will cause
* an {@link IllegalArgumentException} to be thrown.
diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java
index 654a8ed..d7880d3 100644
--- a/core/java/android/view/ViewGroup.java
+++ b/core/java/android/view/ViewGroup.java
@@ -2582,15 +2582,21 @@
* Returns true if this ViewGroup should be considered as a single entity for removal
* when executing an Activity transition. If this is false, child elements will move
* individually during the transition.
+ *
* @return True if the ViewGroup should be acted on together during an Activity transition.
- * The default value is false when the background is null and true when the background
- * is not null or if {@link #getTransitionName()} is not null.
+ * The default value is true when there is a non-null background or if
+ * {@link #getTransitionName()} is not null or if a
+ * non-null {@link android.view.ViewOutlineProvider} other than
+ * {@link android.view.ViewOutlineProvider#BACKGROUND} was given to
+ * {@link #setOutlineProvider(ViewOutlineProvider)} and false otherwise.
*/
public boolean isTransitionGroup() {
if ((mGroupFlags & FLAG_IS_TRANSITION_GROUP_SET) != 0) {
return ((mGroupFlags & FLAG_IS_TRANSITION_GROUP) != 0);
} else {
- return getBackground() != null || getTransitionName() != null;
+ final ViewOutlineProvider outlineProvider = getOutlineProvider();
+ return getBackground() != null || getTransitionName() != null ||
+ (outlineProvider != null && outlineProvider != ViewOutlineProvider.BACKGROUND);
}
}
@@ -6422,8 +6428,8 @@
/**
* Information about how wide the view wants to be. Can be one of the
- * constants FILL_PARENT (replaced by MATCH_PARENT ,
- * in API Level 8) or WRAP_CONTENT. or an exact size.
+ * constants FILL_PARENT (replaced by MATCH_PARENT
+ * in API Level 8) or WRAP_CONTENT, or an exact size.
*/
@ViewDebug.ExportedProperty(category = "layout", mapping = {
@ViewDebug.IntToString(from = MATCH_PARENT, to = "MATCH_PARENT"),
@@ -6433,8 +6439,8 @@
/**
* Information about how tall the view wants to be. Can be one of the
- * constants FILL_PARENT (replaced by MATCH_PARENT ,
- * in API Level 8) or WRAP_CONTENT. or an exact size.
+ * constants FILL_PARENT (replaced by MATCH_PARENT
+ * in API Level 8) or WRAP_CONTENT, or an exact size.
*/
@ViewDebug.ExportedProperty(category = "layout", mapping = {
@ViewDebug.IntToString(from = MATCH_PARENT, to = "MATCH_PARENT"),
diff --git a/core/java/android/view/inputmethod/InputMethodSubtypeArray.java b/core/java/android/view/inputmethod/InputMethodSubtypeArray.java
index 5bef71f..3ff099a 100644
--- a/core/java/android/view/inputmethod/InputMethodSubtypeArray.java
+++ b/core/java/android/view/inputmethod/InputMethodSubtypeArray.java
@@ -203,43 +203,20 @@
}
private static byte[] compress(final byte[] data) {
- ByteArrayOutputStream resultStream = null;
- GZIPOutputStream zipper = null;
- try {
- resultStream = new ByteArrayOutputStream();
- zipper = new GZIPOutputStream(resultStream);
+ try (final ByteArrayOutputStream resultStream = new ByteArrayOutputStream();
+ final GZIPOutputStream zipper = new GZIPOutputStream(resultStream)) {
zipper.write(data);
- } catch(IOException e) {
+ zipper.finish();
+ return resultStream.toByteArray();
+ } catch(Exception e) {
+ Slog.e(TAG, "Failed to compress the data.", e);
return null;
- } finally {
- try {
- if (zipper != null) {
- zipper.close();
- }
- } catch (IOException e) {
- zipper = null;
- Slog.e(TAG, "Failed to close the stream.", e);
- // swallowed, not propagated back to the caller
- }
- try {
- if (resultStream != null) {
- resultStream.close();
- }
- } catch (IOException e) {
- resultStream = null;
- Slog.e(TAG, "Failed to close the stream.", e);
- // swallowed, not propagated back to the caller
- }
}
- return resultStream != null ? resultStream.toByteArray() : null;
}
private static byte[] decompress(final byte[] data, final int expectedSize) {
- ByteArrayInputStream inputStream = null;
- GZIPInputStream unzipper = null;
- try {
- inputStream = new ByteArrayInputStream(data);
- unzipper = new GZIPInputStream(inputStream);
+ try (final ByteArrayInputStream inputStream = new ByteArrayInputStream(data);
+ final GZIPInputStream unzipper = new GZIPInputStream(inputStream)) {
final byte [] result = new byte[expectedSize];
int totalReadBytes = 0;
while (totalReadBytes < result.length) {
@@ -254,25 +231,9 @@
return null;
}
return result;
- } catch(IOException e) {
+ } catch(Exception e) {
+ Slog.e(TAG, "Failed to decompress the data.", e);
return null;
- } finally {
- try {
- if (unzipper != null) {
- unzipper.close();
- }
- } catch (IOException e) {
- Slog.e(TAG, "Failed to close the stream.", e);
- // swallowed, not propagated back to the caller
- }
- try {
- if (inputStream != null) {
- inputStream.close();
- }
- } catch (IOException e) {
- Slog.e(TAG, "Failed to close the stream.", e);
- // swallowed, not propagated back to the caller
- }
}
}
}
diff --git a/core/java/android/webkit/WebResourceResponse.java b/core/java/android/webkit/WebResourceResponse.java
index ad6e9aa..f487a4e 100644
--- a/core/java/android/webkit/WebResourceResponse.java
+++ b/core/java/android/webkit/WebResourceResponse.java
@@ -17,6 +17,7 @@
package android.webkit;
import java.io.InputStream;
+import java.io.StringBufferInputStream;
import java.util.Map;
/**
@@ -40,13 +41,14 @@
*
* @param mimeType the resource response's MIME type, for example text/html
* @param encoding the resource response's encoding
- * @param data the input stream that provides the resource response's data
+ * @param data the input stream that provides the resource response's data. Must not be a
+ * StringBufferInputStream.
*/
public WebResourceResponse(String mimeType, String encoding,
InputStream data) {
mMimeType = mimeType;
mEncoding = encoding;
- mInputStream = data;
+ setData(data);
}
/**
@@ -62,7 +64,8 @@
* and not empty.
* @param responseHeaders the resource response's headers represented as a mapping of header
* name -> header value.
- * @param data the input stream that provides the resource response's data
+ * @param data the input stream that provides the resource response's data. Must not be a
+ * StringBufferInputStream.
*/
public WebResourceResponse(String mimeType, String encoding, int statusCode,
String reasonPhrase, Map<String, String> responseHeaders, InputStream data) {
@@ -178,9 +181,16 @@
* Sets the input stream that provides the resource response's data. Callers
* must implement {@link InputStream#read(byte[]) InputStream.read(byte[])}.
*
- * @param data the input stream that provides the resource response's data
+ * @param data the input stream that provides the resource response's data. Must not be a
+ * StringBufferInputStream.
*/
public void setData(InputStream data) {
+ // If data is (or is a subclass of) StringBufferInputStream
+ if (data != null && StringBufferInputStream.class.isAssignableFrom(data.getClass())) {
+ throw new IllegalArgumentException("StringBufferInputStream is deprecated and must " +
+ "not be passed to a WebResourceResponse");
+ }
+
mInputStream = data;
}
diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java
index 40aee96..592d6e2 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -2143,7 +2143,7 @@
/**
* In addition to the FindListener that the user may set via the WebView.setFindListener
* API, FindActionModeCallback will register it's own FindListener. We keep them separate
- * via this class so that that the two FindListeners can potentially exist at once.
+ * via this class so that the two FindListeners can potentially exist at once.
*/
private class FindListenerDistributor implements FindListener {
private FindListener mFindDialogFindListener;
diff --git a/core/java/android/widget/AbsListView.java b/core/java/android/widget/AbsListView.java
index 6927660..ae10a9a 100644
--- a/core/java/android/widget/AbsListView.java
+++ b/core/java/android/widget/AbsListView.java
@@ -2392,7 +2392,9 @@
lp.itemId = mAdapter.getItemId(position);
}
lp.viewType = mAdapter.getItemViewType(position);
- child.setLayoutParams(lp);
+ if (lp != vlp) {
+ child.setLayoutParams(lp);
+ }
}
class ListItemAccessibilityDelegate extends AccessibilityDelegate {
diff --git a/core/java/android/widget/Editor.java b/core/java/android/widget/Editor.java
index 936da32..d5166f3 100644
--- a/core/java/android/widget/Editor.java
+++ b/core/java/android/widget/Editor.java
@@ -1402,7 +1402,7 @@
blockDisplayList.setLeftTopRightBottom(left, top, right, bottom);
}
- ((HardwareCanvas) canvas).drawRenderNode(blockDisplayList, null,
+ ((HardwareCanvas) canvas).drawRenderNode(blockDisplayList,
0 /* no child clipping, our TextView parent enforces it */);
endOfPreviousBlock = blockEndLine;
diff --git a/core/java/android/widget/OverScroller.java b/core/java/android/widget/OverScroller.java
index a40d4f8..451e493 100644
--- a/core/java/android/widget/OverScroller.java
+++ b/core/java/android/widget/OverScroller.java
@@ -18,7 +18,6 @@
import android.content.Context;
import android.hardware.SensorManager;
-import android.util.FloatMath;
import android.util.Log;
import android.view.ViewConfiguration;
import android.view.animation.AnimationUtils;
@@ -181,9 +180,7 @@
* @return The original velocity less the deceleration, norm of the X and Y velocity vector.
*/
public float getCurrVelocity() {
- float squaredNorm = mScrollerX.mCurrVelocity * mScrollerX.mCurrVelocity;
- squaredNorm += mScrollerY.mCurrVelocity * mScrollerY.mCurrVelocity;
- return FloatMath.sqrt(squaredNorm);
+ return (float) Math.hypot(mScrollerX.mCurrVelocity, mScrollerY.mCurrVelocity);
}
/**
diff --git a/core/java/android/widget/Scroller.java b/core/java/android/widget/Scroller.java
index 5e88a96..357c9c3 100644
--- a/core/java/android/widget/Scroller.java
+++ b/core/java/android/widget/Scroller.java
@@ -19,7 +19,6 @@
import android.content.Context;
import android.hardware.SensorManager;
import android.os.Build;
-import android.util.FloatMath;
import android.view.ViewConfiguration;
import android.view.animation.AnimationUtils;
import android.view.animation.Interpolator;
@@ -425,7 +424,7 @@
float dx = (float) (mFinalX - mStartX);
float dy = (float) (mFinalY - mStartY);
- float hyp = FloatMath.sqrt(dx * dx + dy * dy);
+ float hyp = (float) Math.hypot(dx, dy);
float ndx = dx / hyp;
float ndy = dy / hyp;
@@ -442,7 +441,7 @@
mMode = FLING_MODE;
mFinished = false;
- float velocity = FloatMath.sqrt(velocityX * velocityX + velocityY * velocityY);
+ float velocity = (float) Math.hypot(velocityX, velocityY);
mVelocity = velocity;
mDuration = getSplineFlingDuration(velocity);
diff --git a/core/java/android/widget/StackView.java b/core/java/android/widget/StackView.java
index d2e718c..9e168b8 100644
--- a/core/java/android/widget/StackView.java
+++ b/core/java/android/widget/StackView.java
@@ -1050,10 +1050,8 @@
if (mView != null) {
final LayoutParams viewLp = (LayoutParams) mView.getLayoutParams();
- float d = (float) Math.sqrt(Math.pow(viewLp.horizontalOffset, 2) +
- Math.pow(viewLp.verticalOffset, 2));
- float maxd = (float) Math.sqrt(Math.pow(mSlideAmount, 2) +
- Math.pow(0.4f * mSlideAmount, 2));
+ float d = (float) Math.hypot(viewLp.horizontalOffset, viewLp.verticalOffset);
+ float maxd = (float) Math.hypot(mSlideAmount, 0.4f * mSlideAmount);
if (velocity == 0) {
return (invert ? (1 - d / maxd) : d / maxd) * DEFAULT_ANIMATION_DURATION;
diff --git a/core/java/android/widget/TextClock.java b/core/java/android/widget/TextClock.java
index 4c5c71d..1a86809 100644
--- a/core/java/android/widget/TextClock.java
+++ b/core/java/android/widget/TextClock.java
@@ -226,10 +226,10 @@
if (mFormat12 == null || mFormat24 == null) {
LocaleData ld = LocaleData.get(getContext().getResources().getConfiguration().locale);
if (mFormat12 == null) {
- mFormat12 = ld.timeFormat12;
+ mFormat12 = ld.timeFormat_hm;
}
if (mFormat24 == null) {
- mFormat24 = ld.timeFormat24;
+ mFormat24 = ld.timeFormat_Hm;
}
}
@@ -433,9 +433,9 @@
LocaleData ld = LocaleData.get(getContext().getResources().getConfiguration().locale);
if (format24Requested) {
- mFormat = abc(mFormat24, mFormat12, ld.timeFormat24);
+ mFormat = abc(mFormat24, mFormat12, ld.timeFormat_Hm);
} else {
- mFormat = abc(mFormat12, mFormat24, ld.timeFormat12);
+ mFormat = abc(mFormat12, mFormat24, ld.timeFormat_hm);
}
boolean hadSeconds = mHasSeconds;
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index 0917b32..44ccde0 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -92,7 +92,6 @@
import android.text.style.UpdateAppearance;
import android.text.util.Linkify;
import android.util.AttributeSet;
-import android.util.FloatMath;
import android.util.Log;
import android.util.TypedValue;
import android.view.AccessibilityIterators.TextSegmentIterator;
@@ -4790,7 +4789,7 @@
* make sure the entire cursor gets invalidated instead of
* sometimes missing half a pixel.
*/
- float thick = FloatMath.ceil(mTextPaint.getStrokeWidth());
+ float thick = (float) Math.ceil(mTextPaint.getStrokeWidth());
if (thick < 1.0f) {
thick = 1.0f;
}
@@ -4800,10 +4799,10 @@
// mHighlightPath is guaranteed to be non null at that point.
mHighlightPath.computeBounds(TEMP_RECTF, false);
- invalidate((int) FloatMath.floor(horizontalPadding + TEMP_RECTF.left - thick),
- (int) FloatMath.floor(verticalPadding + TEMP_RECTF.top - thick),
- (int) FloatMath.ceil(horizontalPadding + TEMP_RECTF.right + thick),
- (int) FloatMath.ceil(verticalPadding + TEMP_RECTF.bottom + thick));
+ invalidate((int) Math.floor(horizontalPadding + TEMP_RECTF.left - thick),
+ (int) Math.floor(verticalPadding + TEMP_RECTF.top - thick),
+ (int) Math.ceil(horizontalPadding + TEMP_RECTF.right + thick),
+ (int) Math.ceil(verticalPadding + TEMP_RECTF.bottom + thick));
}
} else {
for (int i = 0; i < mEditor.mCursorCount; i++) {
@@ -6491,7 +6490,7 @@
max = Math.max(max, layout.getLineWidth(i));
}
- return (int) FloatMath.ceil(max);
+ return (int) Math.ceil(max);
}
/**
@@ -6568,7 +6567,7 @@
if (boring == null || boring == UNKNOWN_BORING) {
if (des < 0) {
- des = (int) FloatMath.ceil(Layout.getDesiredWidth(mTransformed, mTextPaint));
+ des = (int) Math.ceil(Layout.getDesiredWidth(mTransformed, mTextPaint));
}
width = des;
} else {
@@ -6598,7 +6597,7 @@
if (hintBoring == null || hintBoring == UNKNOWN_BORING) {
if (hintDes < 0) {
- hintDes = (int) FloatMath.ceil(Layout.getDesiredWidth(mHint, mTextPaint));
+ hintDes = (int) Math.ceil(Layout.getDesiredWidth(mHint, mTextPaint));
}
hintWidth = hintDes;
} else {
@@ -6904,8 +6903,8 @@
* keep leading edge in view.
*/
- int left = (int) FloatMath.floor(layout.getLineLeft(line));
- int right = (int) FloatMath.ceil(layout.getLineRight(line));
+ int left = (int) Math.floor(layout.getLineLeft(line));
+ int right = (int) Math.ceil(layout.getLineRight(line));
if (right - left < hspace) {
scrollx = (right + left) / 2 - hspace / 2;
@@ -6917,10 +6916,10 @@
}
}
} else if (a == Layout.Alignment.ALIGN_RIGHT) {
- int right = (int) FloatMath.ceil(layout.getLineRight(line));
+ int right = (int) Math.ceil(layout.getLineRight(line));
scrollx = right - hspace;
} else { // a == Layout.Alignment.ALIGN_LEFT (will also be the default)
- scrollx = (int) FloatMath.floor(layout.getLineLeft(line));
+ scrollx = (int) Math.floor(layout.getLineLeft(line));
}
if (ht < vspace) {
@@ -6995,8 +6994,8 @@
final int top = layout.getLineTop(line);
final int bottom = layout.getLineTop(line + 1);
- int left = (int) FloatMath.floor(layout.getLineLeft(line));
- int right = (int) FloatMath.ceil(layout.getLineRight(line));
+ int left = (int) Math.floor(layout.getLineLeft(line));
+ int right = (int) Math.ceil(layout.getLineRight(line));
int ht = layout.getHeight();
int hspace = mRight - mLeft - getCompoundPaddingLeft() - getCompoundPaddingRight();
diff --git a/core/java/android/widget/TimePickerClockDelegate.java b/core/java/android/widget/TimePickerClockDelegate.java
index 78ee247..7d01321 100644
--- a/core/java/android/widget/TimePickerClockDelegate.java
+++ b/core/java/android/widget/TimePickerClockDelegate.java
@@ -607,23 +607,32 @@
*/
@Override
public void onValueSelected(int pickerIndex, int newValue, boolean autoAdvance) {
- if (pickerIndex == HOUR_INDEX) {
- if (mAllowAutoAdvance && autoAdvance) {
- updateHeaderHour(newValue, false);
- setCurrentItemShowing(MINUTE_INDEX, true, false);
- mDelegator.announceForAccessibility(newValue + ". " + mSelectMinutes);
- } else {
- updateHeaderHour(newValue, true);
- }
- } else if (pickerIndex == MINUTE_INDEX){
- updateHeaderMinute(newValue, true);
- } else if (pickerIndex == AMPM_INDEX) {
- updateAmPmLabelStates(newValue);
- } else if (pickerIndex == ENABLE_PICKER_INDEX) {
- if (!isTypedTimeFullyLegal()) {
- mTypedTimes.clear();
- }
- finishKbMode();
+ switch (pickerIndex) {
+ case HOUR_INDEX:
+ if (mAllowAutoAdvance && autoAdvance) {
+ updateHeaderHour(newValue, false);
+ setCurrentItemShowing(MINUTE_INDEX, true, false);
+ mDelegator.announceForAccessibility(newValue + ". " + mSelectMinutes);
+ } else {
+ updateHeaderHour(newValue, true);
+ }
+ break;
+ case MINUTE_INDEX:
+ updateHeaderMinute(newValue, true);
+ break;
+ case AMPM_INDEX:
+ updateAmPmLabelStates(newValue);
+ break;
+ case ENABLE_PICKER_INDEX:
+ if (!isTypedTimeFullyLegal()) {
+ mTypedTimes.clear();
+ }
+ finishKbMode();
+ break;
+ }
+
+ if (mOnTimeChangedListener != null) {
+ mOnTimeChangedListener.onTimeChanged(mDelegator, getCurrentHour(), getCurrentMinute());
}
}
diff --git a/core/java/com/android/internal/app/ExternalMediaFormatActivity.java b/core/java/com/android/internal/app/ExternalMediaFormatActivity.java
index 6ed3bdc..fc213c5 100644
--- a/core/java/com/android/internal/app/ExternalMediaFormatActivity.java
+++ b/core/java/com/android/internal/app/ExternalMediaFormatActivity.java
@@ -25,6 +25,7 @@
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
+import android.os.storage.StorageVolume;
import android.util.Log;
/**
@@ -94,6 +95,10 @@
if (which == POSITIVE_BUTTON) {
Intent intent = new Intent(ExternalStorageFormatter.FORMAT_ONLY);
intent.setComponent(ExternalStorageFormatter.COMPONENT_NAME);
+ // Transfer the storage volume to the new intent
+ final StorageVolume storageVolume = getIntent().getParcelableExtra(
+ StorageVolume.EXTRA_STORAGE_VOLUME);
+ intent.putExtra(StorageVolume.EXTRA_STORAGE_VOLUME, storageVolume);
startService(intent);
}
diff --git a/cmds/app_process/sigchain_proxy.cpp b/core/java/com/android/internal/content/ReferrerIntent.aidl
similarity index 74%
copy from cmds/app_process/sigchain_proxy.cpp
copy to core/java/com/android/internal/content/ReferrerIntent.aidl
index bb7a678..7cf6774 100644
--- a/cmds/app_process/sigchain_proxy.cpp
+++ b/core/java/com/android/internal/content/ReferrerIntent.aidl
@@ -1,11 +1,11 @@
/*
- * Copyright (C) 2014 The Android Open Source Project
+ * Copyright 2014, The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
- * http://www.apache.org/licenses/LICENSE-2.0
+ * 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,
@@ -14,4 +14,6 @@
* limitations under the License.
*/
-#include "sigchainlib/sigchain.cc"
+package com.android.internal.content;
+
+parcelable ReferrerIntent;
diff --git a/core/java/com/android/internal/content/ReferrerIntent.java b/core/java/com/android/internal/content/ReferrerIntent.java
new file mode 100644
index 0000000..8d9a1cf
--- /dev/null
+++ b/core/java/com/android/internal/content/ReferrerIntent.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.content;
+
+import android.content.Intent;
+import android.os.Parcel;
+
+/**
+ * Subclass of Intent that also contains referrer (as a package name) information.
+ */
+public class ReferrerIntent extends Intent {
+ public final String mReferrer;
+
+ public ReferrerIntent(Intent baseIntent, String referrer) {
+ super(baseIntent);
+ mReferrer = referrer;
+ }
+
+ public void writeToParcel(Parcel dest, int parcelableFlags) {
+ super.writeToParcel(dest, parcelableFlags);
+ dest.writeString(mReferrer);
+ }
+
+ ReferrerIntent(Parcel in) {
+ readFromParcel(in);
+ mReferrer = in.readString();
+ }
+
+ public static final Creator<ReferrerIntent> CREATOR = new Creator<ReferrerIntent>() {
+ public ReferrerIntent createFromParcel(Parcel source) {
+ return new ReferrerIntent(source);
+ }
+ public ReferrerIntent[] newArray(int size) {
+ return new ReferrerIntent[size];
+ }
+ };
+}
diff --git a/core/java/com/android/internal/os/Zygote.java b/core/java/com/android/internal/os/Zygote.java
index cca340c..fced092 100644
--- a/core/java/com/android/internal/os/Zygote.java
+++ b/core/java/com/android/internal/os/Zygote.java
@@ -20,12 +20,9 @@
import dalvik.system.ZygoteHooks;
import android.system.ErrnoException;
import android.system.Os;
-import android.os.SystemClock;
-import android.util.Slog;
/** @hide */
public final class Zygote {
- private static final String TAG = "Zygote";
/*
* Bit values for "debugFlags" argument. The definitions are duplicated
* in the native code.
@@ -87,15 +84,11 @@
public static int forkAndSpecialize(int uid, int gid, int[] gids, int debugFlags,
int[][] rlimits, int mountExternal, String seInfo, String niceName, int[] fdsToClose,
String instructionSet, String appDataDir) {
- long startTime = SystemClock.elapsedRealtime();
VM_HOOKS.preFork();
- checkTime(startTime, "Zygote.preFork");
int pid = nativeForkAndSpecialize(
uid, gid, gids, debugFlags, rlimits, mountExternal, seInfo, niceName, fdsToClose,
instructionSet, appDataDir);
- checkTime(startTime, "Zygote.nativeForkAndSpecialize");
VM_HOOKS.postForkCommon();
- checkTime(startTime, "Zygote.postForkCommon");
return pid;
}
@@ -104,18 +97,6 @@
String instructionSet, String appDataDir);
/**
- * Temporary hack: check time since start time and log if over a fixed threshold.
- *
- */
- private static void checkTime(long startTime, String where) {
- long now = SystemClock.elapsedRealtime();
- if ((now-startTime) > 1000) {
- // If we are taking more than a second, log about it.
- Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
- }
- }
-
- /**
* Special method to start the system server process. In addition to the
* common actions performed in forkAndSpecialize, the pid of the child
* process is recorded such that the death of the child process will cause
@@ -151,9 +132,7 @@
int[][] rlimits, long permittedCapabilities, long effectiveCapabilities);
private static void callPostForkChildHooks(int debugFlags, String instructionSet) {
- long startTime = SystemClock.elapsedRealtime();
VM_HOOKS.postForkChild(debugFlags, instructionSet);
- checkTime(startTime, "Zygote.callPostForkChildHooks");
}
diff --git a/core/java/com/android/internal/os/ZygoteConnection.java b/core/java/com/android/internal/os/ZygoteConnection.java
index 2ef8a20..24820bc 100644
--- a/core/java/com/android/internal/os/ZygoteConnection.java
+++ b/core/java/com/android/internal/os/ZygoteConnection.java
@@ -37,8 +37,6 @@
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import libcore.io.IoUtils;
-import android.os.SystemClock;
-import android.util.Slog;
/**
* A connection that can make spawn requests.
@@ -93,7 +91,7 @@
new InputStreamReader(socket.getInputStream()), 256);
mSocket.setSoTimeout(CONNECTION_TIMEOUT_MILLIS);
-
+
try {
peer = mSocket.getPeerCredentials();
} catch (IOException ex) {
@@ -105,23 +103,11 @@
}
/**
- * Temporary hack: check time since start time and log if over a fixed threshold.
- *
- */
- private void checkTime(long startTime, String where) {
- long now = SystemClock.elapsedRealtime();
- if ((now-startTime) > 1000) {
- // If we are taking more than a second, log about it.
- Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
- }
- }
-
- /**
* Returns the file descriptor of the associated socket.
*
* @return null-ok; file descriptor
*/
- FileDescriptor getFileDescriptor() {
+ FileDescriptor getFileDesciptor() {
return mSocket.getFileDescriptor();
}
@@ -145,8 +131,6 @@
Arguments parsedArgs = null;
FileDescriptor[] descriptors;
- long startTime = SystemClock.elapsedRealtime();
-
try {
args = readArgumentList();
descriptors = mSocket.getAncillaryFileDescriptors();
@@ -156,7 +140,6 @@
return true;
}
- checkTime(startTime, "zygoteConnection.runOnce: readArgumentList");
if (args == null) {
// EOF reached.
closeSocket();
@@ -188,19 +171,14 @@
", effective=0x" + Long.toHexString(parsedArgs.effectiveCapabilities));
}
-
applyUidSecurityPolicy(parsedArgs, peer, peerSecurityContext);
applyRlimitSecurityPolicy(parsedArgs, peer, peerSecurityContext);
applyInvokeWithSecurityPolicy(parsedArgs, peer, peerSecurityContext);
applyseInfoSecurityPolicy(parsedArgs, peer, peerSecurityContext);
- checkTime(startTime, "zygoteConnection.runOnce: apply security policies");
-
applyDebuggerSystemProperty(parsedArgs);
applyInvokeWithSystemProperty(parsedArgs);
- checkTime(startTime, "zygoteConnection.runOnce: apply security policies");
-
int[][] rlimits = null;
if (parsedArgs.rlimits != null) {
@@ -242,12 +220,10 @@
fd = null;
- checkTime(startTime, "zygoteConnection.runOnce: preForkAndSpecialize");
pid = Zygote.forkAndSpecialize(parsedArgs.uid, parsedArgs.gid, parsedArgs.gids,
parsedArgs.debugFlags, rlimits, parsedArgs.mountExternal, parsedArgs.seInfo,
parsedArgs.niceName, fdsToClose, parsedArgs.instructionSet,
parsedArgs.appDataDir);
- checkTime(startTime, "zygoteConnection.runOnce: postForkAndSpecialize");
} catch (IOException ex) {
logAndPrintError(newStderr, "Exception creating pipe", ex);
} catch (ErrnoException ex) {
@@ -620,7 +596,7 @@
}
// See bug 1092107: large argc can be used for a DOS attack
- if (argc > MAX_ZYGOTE_ARGC) {
+ if (argc > MAX_ZYGOTE_ARGC) {
throw new IOException("max arg count exceeded");
}
@@ -637,7 +613,7 @@
}
/**
- * Applies zygote security policy per bugs #875058 and #1082165.
+ * Applies zygote security policy per bugs #875058 and #1082165.
* Based on the credentials of the process issuing a zygote command:
* <ol>
* <li> uid 0 (root) may specify any uid, gid, and setgroups() list
@@ -668,7 +644,7 @@
/* In normal operation, SYSTEM_UID can only specify a restricted
* set of UIDs. In factory test mode, SYSTEM_UID may specify any uid.
*/
- uidRestricted
+ uidRestricted
= !(factoryTest.equals("1") || factoryTest.equals("2"));
if (uidRestricted
diff --git a/core/java/com/android/internal/os/ZygoteInit.java b/core/java/com/android/internal/os/ZygoteInit.java
index 4dde217..46850da 100644
--- a/core/java/com/android/internal/os/ZygoteInit.java
+++ b/core/java/com/android/internal/os/ZygoteInit.java
@@ -91,12 +91,6 @@
private static Resources mResources;
/**
- * The number of times that the main Zygote loop
- * should run before calling gc() again.
- */
- static final int GC_LOOP_COUNT = 10;
-
- /**
* The name of a resource file that contains classes to preload.
*/
private static final String PRELOADED_CLASSES = "preloaded-classes";
@@ -301,11 +295,6 @@
float defaultUtilization = runtime.getTargetHeapUtilization();
runtime.setTargetHeapUtilization(0.8f);
- // Start with a clean slate.
- System.gc();
- runtime.runFinalizationSync();
- Debug.startAllocCounting();
-
try {
BufferedReader br
= new BufferedReader(new InputStreamReader(is), 256);
@@ -324,15 +313,6 @@
Log.v(TAG, "Preloading " + line + "...");
}
Class.forName(line);
- if (Debug.getGlobalAllocSize() > PRELOAD_GC_THRESHOLD) {
- if (false) {
- Log.v(TAG,
- " GC at " + Debug.getGlobalAllocSize());
- }
- System.gc();
- runtime.runFinalizationSync();
- Debug.resetGlobalAllocSize();
- }
count++;
} catch (ClassNotFoundException e) {
Log.w(TAG, "Class not found for preloading: " + line);
@@ -362,8 +342,6 @@
// Fill in dex caches with classes, fields, and methods brought in by preloading.
runtime.preloadDexCaches();
- Debug.stopAllocCounting();
-
// Bring back root. We'll need it later.
setEffectiveUser(ROOT_UID);
setEffectiveGroup(ROOT_GID);
@@ -381,10 +359,7 @@
private static void preloadResources() {
final VMRuntime runtime = VMRuntime.getRuntime();
- Debug.startAllocCounting();
try {
- System.gc();
- runtime.runFinalizationSync();
mResources = Resources.getSystem();
mResources.startPreloading();
if (PRELOAD_RESOURCES) {
@@ -409,22 +384,12 @@
mResources.finishPreloading();
} catch (RuntimeException e) {
Log.w(TAG, "Failure preloading resources", e);
- } finally {
- Debug.stopAllocCounting();
}
}
private static int preloadColorStateLists(VMRuntime runtime, TypedArray ar) {
int N = ar.length();
for (int i=0; i<N; i++) {
- if (Debug.getGlobalAllocSize() > PRELOAD_GC_THRESHOLD) {
- if (false) {
- Log.v(TAG, " GC at " + Debug.getGlobalAllocSize());
- }
- System.gc();
- runtime.runFinalizationSync();
- Debug.resetGlobalAllocSize();
- }
int id = ar.getResourceId(i, 0);
if (false) {
Log.v(TAG, "Preloading resource #" + Integer.toHexString(id));
@@ -445,14 +410,6 @@
private static int preloadDrawables(VMRuntime runtime, TypedArray ar) {
int N = ar.length();
for (int i=0; i<N; i++) {
- if (Debug.getGlobalAllocSize() > PRELOAD_GC_THRESHOLD) {
- if (false) {
- Log.v(TAG, " GC at " + Debug.getGlobalAllocSize());
- }
- System.gc();
- runtime.runFinalizationSync();
- Debug.resetGlobalAllocSize();
- }
int id = ar.getResourceId(i, 0);
if (false) {
Log.v(TAG, "Preloading resource #" + Integer.toHexString(id));
@@ -474,7 +431,7 @@
* softly- and final-reachable objects, along with any other garbage.
* This is only useful just before a fork().
*/
- /*package*/ static void gc() {
+ /*package*/ static void gcAndFinalize() {
final VMRuntime runtime = VMRuntime.getRuntime();
/* runFinalizationSync() lets finalizers be called in Zygote,
@@ -483,9 +440,6 @@
System.gc();
runtime.runFinalizationSync();
System.gc();
- runtime.runFinalizationSync();
- System.gc();
- runtime.runFinalizationSync();
}
/**
@@ -676,7 +630,7 @@
SamplingProfilerIntegration.writeZygoteSnapshot();
// Do an initial gc to clean up after startup
- gc();
+ gcAndFinalize();
// Disable tracing so that forked processes do not inherit stale tracing tags from
// Zygote.
@@ -745,27 +699,9 @@
fds.add(sServerSocket.getFileDescriptor());
peers.add(null);
- int loopCount = GC_LOOP_COUNT;
while (true) {
int index;
- /*
- * Call gc() before we block in select().
- * It's work that has to be done anyway, and it's better
- * to avoid making every child do it. It will also
- * madvise() any free memory as a side-effect.
- *
- * Don't call it every time, because walking the entire
- * heap is a lot of overhead to free a few hundred bytes.
- */
- if (loopCount <= 0) {
- gc();
- loopCount = GC_LOOP_COUNT;
- } else {
- loopCount--;
- }
-
-
try {
fdArray = fds.toArray(fdArray);
index = selectReadable(fdArray);
@@ -778,7 +714,7 @@
} else if (index == 0) {
ZygoteConnection newPeer = acceptCommandPeer(abiList);
peers.add(newPeer);
- fds.add(newPeer.getFileDescriptor());
+ fds.add(newPeer.getFileDesciptor());
} else {
boolean done;
done = peers.get(index).runOnce();
diff --git a/core/java/com/android/internal/widget/multiwaveview/GlowPadView.java b/core/java/com/android/internal/widget/multiwaveview/GlowPadView.java
index b680fab..11ac19e 100644
--- a/core/java/com/android/internal/widget/multiwaveview/GlowPadView.java
+++ b/core/java/com/android/internal/widget/multiwaveview/GlowPadView.java
@@ -863,7 +863,7 @@
// tx and ty are relative to wave center
float tx = eventX - mWaveCenterX;
float ty = eventY - mWaveCenterY;
- float touchRadius = (float) Math.sqrt(dist2(tx, ty));
+ float touchRadius = (float) Math.hypot(tx, ty);
final float scale = touchRadius > mOuterRadius ? mOuterRadius / touchRadius : 1.0f;
float limitX = tx * scale;
float limitY = ty * scale;
diff --git a/core/java/com/android/internal/widget/multiwaveview/PointCloud.java b/core/java/com/android/internal/widget/multiwaveview/PointCloud.java
index f299935..6f26b99 100644
--- a/core/java/com/android/internal/widget/multiwaveview/PointCloud.java
+++ b/core/java/com/android/internal/widget/multiwaveview/PointCloud.java
@@ -22,7 +22,6 @@
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.drawable.Drawable;
-import android.util.FloatMath;
import android.util.Log;
public class PointCloud {
@@ -151,8 +150,8 @@
float eta = PI/2.0f;
float dEta = 2.0f * PI / pointsInBand;
for (int i = 0; i < pointsInBand; i++) {
- float x = r * FloatMath.cos(eta);
- float y = r * FloatMath.sin(eta);
+ float x = r * (float) Math.cos(eta);
+ float y = r * (float) Math.sin(eta);
eta += dEta;
mPointCloud.add(new Point(x, y, r));
}
@@ -167,32 +166,24 @@
return mScale;
}
- private static float hypot(float x, float y) {
- return FloatMath.sqrt(x*x + y*y);
- }
-
- private static float max(float a, float b) {
- return a > b ? a : b;
- }
-
public int getAlphaForPoint(Point point) {
// Contribution from positional glow
- float glowDistance = hypot(glowManager.x - point.x, glowManager.y - point.y);
+ float glowDistance = (float) Math.hypot(glowManager.x - point.x, glowManager.y - point.y);
float glowAlpha = 0.0f;
if (glowDistance < glowManager.radius) {
- float cosf = FloatMath.cos(PI * 0.25f * glowDistance / glowManager.radius);
- glowAlpha = glowManager.alpha * max(0.0f, (float) Math.pow(cosf, 10.0f));
+ float cosf = (float) Math.cos(PI * 0.25f * glowDistance / glowManager.radius);
+ glowAlpha = glowManager.alpha * Math.max(0.0f, (float) Math.pow(cosf, 10.0f));
}
// Compute contribution from Wave
- float radius = hypot(point.x, point.y);
+ float radius = (float) Math.hypot(point.x, point.y);
float waveAlpha = 0.0f;
if (radius < waveManager.radius * 2) {
float distanceToWaveRing = (radius - waveManager.radius);
- float cosf = FloatMath.cos(PI * 0.5f * distanceToWaveRing / waveManager.radius);
- waveAlpha = waveManager.alpha * max(0.0f, (float) Math.pow(cosf, 6.0f));
+ float cosf = (float) Math.cos(PI * 0.5f * distanceToWaveRing / waveManager.radius);
+ waveAlpha = waveManager.alpha * Math.max(0.0f, (float) Math.pow(cosf, 6.0f));
}
- return (int) (max(glowAlpha, waveAlpha) * 255);
+ return (int) (Math.max(glowAlpha, waveAlpha) * 255);
}
private float interp(float min, float max, float f) {
diff --git a/core/jni/Android.mk b/core/jni/Android.mk
index dbaa4b8..245e0d2 100644
--- a/core/jni/Android.mk
+++ b/core/jni/Android.mk
@@ -1,5 +1,6 @@
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
+LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
LOCAL_CFLAGS += -DHAVE_CONFIG_H -DKHTML_NO_EXCEPTIONS -DGKWQ_NO_JAVA
LOCAL_CFLAGS += -DNO_SUPPORT_JS_BINDING -DQT_NO_WHEELEVENT -DKHTML_NO_XBL
@@ -84,7 +85,6 @@
android_util_Binder.cpp \
android_util_EventLog.cpp \
android_util_Log.cpp \
- android_util_FloatMath.cpp \
android_util_Process.cpp \
android_util_StringBlock.cpp \
android_util_XmlBlock.cpp \
@@ -255,13 +255,10 @@
LOCAL_SHARED_LIBRARIES += \
libdl
+
# we need to access the private Bionic header
# <bionic_tls.h> in com_google_android_gles_jni_GLImpl.cpp
-LOCAL_CFLAGS += -I$(LOCAL_PATH)/../../../../bionic/libc/private
-
-ifeq ($(WITH_MALLOC_LEAK_CHECK),true)
- LOCAL_CFLAGS += -DMALLOC_LEAK_CHECK
-endif
+LOCAL_C_INCLUDES += bionic/libc/private
LOCAL_MODULE:= libandroid_runtime
diff --git a/core/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp
index 4d17877..7dd5c57 100644
--- a/core/jni/AndroidRuntime.cpp
+++ b/core/jni/AndroidRuntime.cpp
@@ -95,8 +95,6 @@
extern int register_android_media_JetPlayer(JNIEnv *env);
extern int register_android_media_ToneGenerator(JNIEnv *env);
-extern int register_android_util_FloatMath(JNIEnv* env);
-
namespace android {
/*
@@ -1228,7 +1226,6 @@
REG_JNI(register_android_os_SystemClock),
REG_JNI(register_android_util_EventLog),
REG_JNI(register_android_util_Log),
- REG_JNI(register_android_util_FloatMath),
REG_JNI(register_android_content_AssetManager),
REG_JNI(register_android_content_StringBlock),
REG_JNI(register_android_content_XmlBlock),
diff --git a/core/jni/android/graphics/Graphics.cpp b/core/jni/android/graphics/Graphics.cpp
index d7b75db..f0585a3 100644
--- a/core/jni/android/graphics/Graphics.cpp
+++ b/core/jni/android/graphics/Graphics.cpp
@@ -166,10 +166,6 @@
static jclass gCanvas_class;
static jfieldID gCanvas_nativeInstanceID;
-static jclass gPaint_class;
-static jfieldID gPaint_nativeInstanceID;
-static jfieldID gPaint_nativeTypefaceID;
-
static jclass gPicture_class;
static jfieldID gPicture_nativeInstanceID;
@@ -370,25 +366,6 @@
return c;
}
-android::Paint* GraphicsJNI::getNativePaint(JNIEnv* env, jobject paint) {
- SkASSERT(env);
- SkASSERT(paint);
- SkASSERT(env->IsInstanceOf(paint, gPaint_class));
- jlong paintHandle = env->GetLongField(paint, gPaint_nativeInstanceID);
- android::Paint* p = reinterpret_cast<android::Paint*>(paintHandle);
- SkASSERT(p);
- return p;
-}
-
-android::TypefaceImpl* GraphicsJNI::getNativeTypeface(JNIEnv* env, jobject paint) {
- SkASSERT(env);
- SkASSERT(paint);
- SkASSERT(env->IsInstanceOf(paint, gPaint_class));
- jlong typefaceHandle = env->GetLongField(paint, gPaint_nativeTypefaceID);
- android::TypefaceImpl* p = reinterpret_cast<android::TypefaceImpl*>(typefaceHandle);
- return p;
-}
-
SkRegion* GraphicsJNI::getNativeRegion(JNIEnv* env, jobject region)
{
SkASSERT(env);
@@ -728,10 +705,6 @@
gCanvas_class = make_globalref(env, "android/graphics/Canvas");
gCanvas_nativeInstanceID = getFieldIDCheck(env, gCanvas_class, "mNativeCanvasWrapper", "J");
- gPaint_class = make_globalref(env, "android/graphics/Paint");
- gPaint_nativeInstanceID = getFieldIDCheck(env, gPaint_class, "mNativePaint", "J");
- gPaint_nativeTypefaceID = getFieldIDCheck(env, gPaint_class, "mNativeTypeface", "J");
-
gPicture_class = make_globalref(env, "android/graphics/Picture");
gPicture_nativeInstanceID = getFieldIDCheck(env, gPicture_class, "mNativePicture", "J");
diff --git a/core/jni/android/graphics/GraphicsJNI.h b/core/jni/android/graphics/GraphicsJNI.h
index dcc97e5..e0200aa 100644
--- a/core/jni/android/graphics/GraphicsJNI.h
+++ b/core/jni/android/graphics/GraphicsJNI.h
@@ -1,6 +1,8 @@
#ifndef GraphicsJNI_DEFINED
#define GraphicsJNI_DEFINED
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wunused-parameter"
#include "SkBitmap.h"
#include "SkDevice.h"
#include "SkPixelRef.h"
@@ -8,6 +10,8 @@
#include "SkPoint.h"
#include "SkRect.h"
#include "SkImageDecoder.h"
+#pragma GCC diagnostic pop
+
#include <jni.h>
class SkBitmapRegionDecoder;
@@ -48,8 +52,6 @@
static void point_to_jpointf(const SkPoint& point, JNIEnv*, jobject jpointf);
static SkCanvas* getNativeCanvas(JNIEnv*, jobject canvas);
- static android::Paint* getNativePaint(JNIEnv*, jobject paint);
- static android::TypefaceImpl* getNativeTypeface(JNIEnv*, jobject paint);
static SkBitmap* getNativeBitmap(JNIEnv*, jobject bitmap);
static SkRegion* getNativeRegion(JNIEnv*, jobject region);
diff --git a/core/jni/android/graphics/Movie.cpp b/core/jni/android/graphics/Movie.cpp
index 226f83e..c0c835f 100644
--- a/core/jni/android/graphics/Movie.cpp
+++ b/core/jni/android/graphics/Movie.cpp
@@ -68,7 +68,7 @@
}
static void movie_draw(JNIEnv* env, jobject movie, jobject canvas,
- jfloat fx, jfloat fy, jobject jpaint) {
+ jfloat fx, jfloat fy, jlong paintHandle) {
NPE_CHECK_RETURN_VOID(env, movie);
NPE_CHECK_RETURN_VOID(env, canvas);
// its OK for paint to be null
@@ -76,7 +76,7 @@
SkMovie* m = J2Movie(env, movie);
SkCanvas* c = GraphicsJNI::getNativeCanvas(env, canvas);
const SkBitmap& b = m->bitmap();
- const SkPaint* p = jpaint ? GraphicsJNI::getNativePaint(env, jpaint) : NULL;
+ const android::Paint* p = reinterpret_cast<android::Paint*>(paintHandle);
c->drawBitmap(b, fx, fy, p);
}
@@ -146,7 +146,7 @@
{ "isOpaque", "()Z", (void*)movie_isOpaque },
{ "duration", "()I", (void*)movie_duration },
{ "setTime", "(I)Z", (void*)movie_setTime },
- { "draw", "(Landroid/graphics/Canvas;FFLandroid/graphics/Paint;)V",
+ { "nDraw", "(Landroid/graphics/Canvas;FFJ)V",
(void*)movie_draw },
{ "nativeDecodeAsset", "(J)Landroid/graphics/Movie;",
(void*)movie_decodeAsset },
diff --git a/core/jni/android/graphics/NinePatchPeeker.cpp b/core/jni/android/graphics/NinePatchPeeker.cpp
index 1dafa1b..2644888 100644
--- a/core/jni/android/graphics/NinePatchPeeker.cpp
+++ b/core/jni/android/graphics/NinePatchPeeker.cpp
@@ -37,14 +37,7 @@
// now update our host to force index or 32bit config
// 'cause we don't want 565 predithered, since as a 9patch, we know
// we will be stretched, and therefore we want to dither afterwards.
- SkImageDecoder::PrefConfigTable table;
- table.fPrefFor_8Index_NoAlpha_src = SkBitmap::kIndex8_Config;
- table.fPrefFor_8Index_YesAlpha_src = SkBitmap::kIndex8_Config;
- table.fPrefFor_8Gray_src = SkBitmap::kARGB_8888_Config;
- table.fPrefFor_8bpc_NoAlpha_src = SkBitmap::kARGB_8888_Config;
- table.fPrefFor_8bpc_YesAlpha_src = SkBitmap::kARGB_8888_Config;
-
- mHost->setPrefConfigTable(table);
+ mHost->setPreserveSrcDepth(true);
} else if (!strcmp("npLb", tag) && length == sizeof(int32_t) * 4) {
mHasInsets = true;
memcpy(&mOpticalInsets, data, sizeof(int32_t) * 4);
diff --git a/core/jni/android/graphics/Paint.cpp b/core/jni/android/graphics/Paint.cpp
index 6b02326..47e7566 100644
--- a/core/jni/android/graphics/Paint.cpp
+++ b/core/jni/android/graphics/Paint.cpp
@@ -61,6 +61,10 @@
static jclass gFontMetricsInt_class;
static JMetricsID gFontMetricsInt_fieldID;
+static jclass gPaint_class;
+static jfieldID gPaint_nativeInstanceID;
+static jfieldID gPaint_nativeTypefaceID;
+
static void defaultSettingsForAndroid(Paint* paint) {
// GlyphID encoding is required because we are using Harfbuzz shaping
paint->setTextEncoding(Paint::kGlyphID_TextEncoding);
@@ -72,6 +76,25 @@
AFTER, AT_OR_AFTER, BEFORE, AT_OR_BEFORE, AT
};
+ static Paint* getNativePaint(JNIEnv* env, jobject paint) {
+ SkASSERT(env);
+ SkASSERT(paint);
+ SkASSERT(env->IsInstanceOf(paint, gPaint_class));
+ jlong paintHandle = env->GetLongField(paint, gPaint_nativeInstanceID);
+ android::Paint* p = reinterpret_cast<android::Paint*>(paintHandle);
+ SkASSERT(p);
+ return p;
+ }
+
+ static TypefaceImpl* getNativeTypeface(JNIEnv* env, jobject paint) {
+ SkASSERT(env);
+ SkASSERT(paint);
+ SkASSERT(env->IsInstanceOf(paint, gPaint_class));
+ jlong typefaceHandle = env->GetLongField(paint, gPaint_nativeTypefaceID);
+ android::TypefaceImpl* p = reinterpret_cast<android::TypefaceImpl*>(typefaceHandle);
+ return p;
+ }
+
static void finalizer(JNIEnv* env, jobject clazz, jlong objHandle) {
Paint* obj = reinterpret_cast<Paint*>(objHandle);
delete obj;
@@ -106,7 +129,7 @@
static jint getFlags(JNIEnv* env, jobject paint) {
NPE_CHECK_RETURN_ZERO(env, paint);
- Paint* nativePaint = GraphicsJNI::getNativePaint(env, paint);
+ Paint* nativePaint = getNativePaint(env, paint);
uint32_t result = nativePaint->getFlags();
result &= ~sFilterBitmapFlag; // Filtering no longer stored in this bit. Mask away.
if (nativePaint->getFilterLevel() != Paint::kNone_FilterLevel) {
@@ -117,7 +140,7 @@
static void setFlags(JNIEnv* env, jobject paint, jint flags) {
NPE_CHECK_RETURN_VOID(env, paint);
- Paint* nativePaint = GraphicsJNI::getNativePaint(env, paint);
+ Paint* nativePaint = getNativePaint(env, paint);
// Instead of modifying 0x02, change the filter level.
nativePaint->setFilterLevel(flags & sFilterBitmapFlag
? Paint::kLow_FilterLevel
@@ -132,55 +155,55 @@
static jint getHinting(JNIEnv* env, jobject paint) {
NPE_CHECK_RETURN_ZERO(env, paint);
- return GraphicsJNI::getNativePaint(env, paint)->getHinting()
+ return getNativePaint(env, paint)->getHinting()
== Paint::kNo_Hinting ? 0 : 1;
}
static void setHinting(JNIEnv* env, jobject paint, jint mode) {
NPE_CHECK_RETURN_VOID(env, paint);
- GraphicsJNI::getNativePaint(env, paint)->setHinting(
+ getNativePaint(env, paint)->setHinting(
mode == 0 ? Paint::kNo_Hinting : Paint::kNormal_Hinting);
}
static void setAntiAlias(JNIEnv* env, jobject paint, jboolean aa) {
NPE_CHECK_RETURN_VOID(env, paint);
- GraphicsJNI::getNativePaint(env, paint)->setAntiAlias(aa);
+ getNativePaint(env, paint)->setAntiAlias(aa);
}
static void setLinearText(JNIEnv* env, jobject paint, jboolean linearText) {
NPE_CHECK_RETURN_VOID(env, paint);
- GraphicsJNI::getNativePaint(env, paint)->setLinearText(linearText);
+ getNativePaint(env, paint)->setLinearText(linearText);
}
static void setSubpixelText(JNIEnv* env, jobject paint, jboolean subpixelText) {
NPE_CHECK_RETURN_VOID(env, paint);
- GraphicsJNI::getNativePaint(env, paint)->setSubpixelText(subpixelText);
+ getNativePaint(env, paint)->setSubpixelText(subpixelText);
}
static void setUnderlineText(JNIEnv* env, jobject paint, jboolean underlineText) {
NPE_CHECK_RETURN_VOID(env, paint);
- GraphicsJNI::getNativePaint(env, paint)->setUnderlineText(underlineText);
+ getNativePaint(env, paint)->setUnderlineText(underlineText);
}
static void setStrikeThruText(JNIEnv* env, jobject paint, jboolean strikeThruText) {
NPE_CHECK_RETURN_VOID(env, paint);
- GraphicsJNI::getNativePaint(env, paint)->setStrikeThruText(strikeThruText);
+ getNativePaint(env, paint)->setStrikeThruText(strikeThruText);
}
static void setFakeBoldText(JNIEnv* env, jobject paint, jboolean fakeBoldText) {
NPE_CHECK_RETURN_VOID(env, paint);
- GraphicsJNI::getNativePaint(env, paint)->setFakeBoldText(fakeBoldText);
+ getNativePaint(env, paint)->setFakeBoldText(fakeBoldText);
}
static void setFilterBitmap(JNIEnv* env, jobject paint, jboolean filterBitmap) {
NPE_CHECK_RETURN_VOID(env, paint);
- GraphicsJNI::getNativePaint(env, paint)->setFilterLevel(
+ getNativePaint(env, paint)->setFilterLevel(
filterBitmap ? Paint::kLow_FilterLevel : Paint::kNone_FilterLevel);
}
static void setDither(JNIEnv* env, jobject paint, jboolean dither) {
NPE_CHECK_RETURN_VOID(env, paint);
- GraphicsJNI::getNativePaint(env, paint)->setDither(dither);
+ getNativePaint(env, paint)->setDither(dither);
}
static jint getStyle(JNIEnv* env, jobject clazz,jlong objHandle) {
@@ -197,45 +220,45 @@
static jint getColor(JNIEnv* env, jobject paint) {
NPE_CHECK_RETURN_ZERO(env, paint);
int color;
- color = GraphicsJNI::getNativePaint(env, paint)->getColor();
+ color = getNativePaint(env, paint)->getColor();
return static_cast<jint>(color);
}
static jint getAlpha(JNIEnv* env, jobject paint) {
NPE_CHECK_RETURN_ZERO(env, paint);
int alpha;
- alpha = GraphicsJNI::getNativePaint(env, paint)->getAlpha();
+ alpha = getNativePaint(env, paint)->getAlpha();
return static_cast<jint>(alpha);
}
static void setColor(JNIEnv* env, jobject paint, jint color) {
NPE_CHECK_RETURN_VOID(env, paint);
- GraphicsJNI::getNativePaint(env, paint)->setColor(color);
+ getNativePaint(env, paint)->setColor(color);
}
static void setAlpha(JNIEnv* env, jobject paint, jint a) {
NPE_CHECK_RETURN_VOID(env, paint);
- GraphicsJNI::getNativePaint(env, paint)->setAlpha(a);
+ getNativePaint(env, paint)->setAlpha(a);
}
static jfloat getStrokeWidth(JNIEnv* env, jobject paint) {
NPE_CHECK_RETURN_ZERO(env, paint);
- return SkScalarToFloat(GraphicsJNI::getNativePaint(env, paint)->getStrokeWidth());
+ return SkScalarToFloat(getNativePaint(env, paint)->getStrokeWidth());
}
static void setStrokeWidth(JNIEnv* env, jobject paint, jfloat width) {
NPE_CHECK_RETURN_VOID(env, paint);
- GraphicsJNI::getNativePaint(env, paint)->setStrokeWidth(width);
+ getNativePaint(env, paint)->setStrokeWidth(width);
}
static jfloat getStrokeMiter(JNIEnv* env, jobject paint) {
NPE_CHECK_RETURN_ZERO(env, paint);
- return SkScalarToFloat(GraphicsJNI::getNativePaint(env, paint)->getStrokeMiter());
+ return SkScalarToFloat(getNativePaint(env, paint)->getStrokeMiter());
}
static void setStrokeMiter(JNIEnv* env, jobject paint, jfloat miter) {
NPE_CHECK_RETURN_VOID(env, paint);
- GraphicsJNI::getNativePaint(env, paint)->setStrokeMiter(miter);
+ getNativePaint(env, paint)->setStrokeMiter(miter);
}
static jint getStrokeCap(JNIEnv* env, jobject clazz, jlong objHandle) {
@@ -370,44 +393,44 @@
static jboolean isElegantTextHeight(JNIEnv* env, jobject paint) {
NPE_CHECK_RETURN_ZERO(env, paint);
- Paint* obj = GraphicsJNI::getNativePaint(env, paint);
+ Paint* obj = getNativePaint(env, paint);
return obj->getFontVariant() == VARIANT_ELEGANT;
}
static void setElegantTextHeight(JNIEnv* env, jobject paint, jboolean aa) {
NPE_CHECK_RETURN_VOID(env, paint);
- Paint* obj = GraphicsJNI::getNativePaint(env, paint);
+ Paint* obj = getNativePaint(env, paint);
obj->setFontVariant(aa ? VARIANT_ELEGANT : VARIANT_DEFAULT);
}
static jfloat getTextSize(JNIEnv* env, jobject paint) {
NPE_CHECK_RETURN_ZERO(env, paint);
- return SkScalarToFloat(GraphicsJNI::getNativePaint(env, paint)->getTextSize());
+ return SkScalarToFloat(getNativePaint(env, paint)->getTextSize());
}
static void setTextSize(JNIEnv* env, jobject paint, jfloat textSize) {
NPE_CHECK_RETURN_VOID(env, paint);
- GraphicsJNI::getNativePaint(env, paint)->setTextSize(textSize);
+ getNativePaint(env, paint)->setTextSize(textSize);
}
static jfloat getTextScaleX(JNIEnv* env, jobject paint) {
NPE_CHECK_RETURN_ZERO(env, paint);
- return SkScalarToFloat(GraphicsJNI::getNativePaint(env, paint)->getTextScaleX());
+ return SkScalarToFloat(getNativePaint(env, paint)->getTextScaleX());
}
static void setTextScaleX(JNIEnv* env, jobject paint, jfloat scaleX) {
NPE_CHECK_RETURN_VOID(env, paint);
- GraphicsJNI::getNativePaint(env, paint)->setTextScaleX(scaleX);
+ getNativePaint(env, paint)->setTextScaleX(scaleX);
}
static jfloat getTextSkewX(JNIEnv* env, jobject paint) {
NPE_CHECK_RETURN_ZERO(env, paint);
- return SkScalarToFloat(GraphicsJNI::getNativePaint(env, paint)->getTextSkewX());
+ return SkScalarToFloat(getNativePaint(env, paint)->getTextSkewX());
}
static void setTextSkewX(JNIEnv* env, jobject paint, jfloat skewX) {
NPE_CHECK_RETURN_VOID(env, paint);
- GraphicsJNI::getNativePaint(env, paint)->setTextSkewX(skewX);
+ getNativePaint(env, paint)->setTextSkewX(skewX);
}
static jfloat getLetterSpacing(JNIEnv* env, jobject clazz, jlong paintHandle) {
@@ -436,8 +459,8 @@
const int kElegantAscent = 1900;
const int kElegantDescent = -500;
const int kElegantLeading = 0;
- Paint* paint = GraphicsJNI::getNativePaint(env, jpaint);
- TypefaceImpl* typeface = GraphicsJNI::getNativeTypeface(env, jpaint);
+ Paint* paint = getNativePaint(env, jpaint);
+ TypefaceImpl* typeface = getNativeTypeface(env, jpaint);
typeface = TypefaceImpl_resolveDefault(typeface);
FakedFont baseFont = typeface->fFontCollection->baseFontFaked(typeface->fStyle);
float saveSkewX = paint->getTextSkewX();
@@ -525,12 +548,12 @@
return 0;
}
- Paint* paint = GraphicsJNI::getNativePaint(env, jpaint);
+ Paint* paint = getNativePaint(env, jpaint);
const jchar* textArray = env->GetCharArrayElements(text, NULL);
jfloat result = 0;
Layout layout;
- TypefaceImpl* typeface = GraphicsJNI::getNativeTypeface(env, jpaint);
+ TypefaceImpl* typeface = getNativeTypeface(env, jpaint);
MinikinUtils::doLayout(&layout, paint, bidiFlags, typeface, textArray, index, count, textLength);
result = layout.getAdvance();
env->ReleaseCharArrayElements(text, const_cast<jchar*>(textArray), JNI_ABORT);
@@ -553,11 +576,11 @@
}
const jchar* textArray = env->GetStringChars(text, NULL);
- Paint* paint = GraphicsJNI::getNativePaint(env, jpaint);
+ Paint* paint = getNativePaint(env, jpaint);
jfloat width = 0;
Layout layout;
- TypefaceImpl* typeface = GraphicsJNI::getNativeTypeface(env, jpaint);
+ TypefaceImpl* typeface = getNativeTypeface(env, jpaint);
MinikinUtils::doLayout(&layout, paint, bidiFlags, typeface, textArray, start, count, textLength);
width = layout.getAdvance();
@@ -575,11 +598,11 @@
}
const jchar* textArray = env->GetStringChars(text, NULL);
- Paint* paint = GraphicsJNI::getNativePaint(env, jpaint);
+ Paint* paint = getNativePaint(env, jpaint);
jfloat width = 0;
Layout layout;
- TypefaceImpl* typeface = GraphicsJNI::getNativeTypeface(env, jpaint);
+ TypefaceImpl* typeface = getNativeTypeface(env, jpaint);
MinikinUtils::doLayout(&layout, paint, bidiFlags, typeface, textArray, 0, textLength, textLength);
width = layout.getAdvance();
@@ -818,7 +841,7 @@
static int breakText(JNIEnv* env, const Paint& paint, TypefaceImpl* typeface, const jchar text[],
int count, float maxWidth, jint bidiFlags, jfloatArray jmeasured,
- Paint::TextBufferDirection textBufferDirection) {
+ const bool forwardScan) {
size_t measuredCount = 0;
float measured = 0;
@@ -826,7 +849,7 @@
MinikinUtils::doLayout(&layout, &paint, bidiFlags, typeface, text, 0, count, count);
float* advances = new float[count];
layout.getAdvances(advances);
- const bool forwardScan = (textBufferDirection == Paint::kForward_TextBufferDirection);
+
for (int i = 0; i < count; i++) {
// traverse in the given direction
int index = forwardScan ? i : (count - i - 1);
@@ -857,13 +880,13 @@
Paint* paint = reinterpret_cast<Paint*>(paintHandle);
TypefaceImpl* typeface = reinterpret_cast<TypefaceImpl*>(typefaceHandle);
- Paint::TextBufferDirection tbd;
+ bool forwardTextDirection;
if (count < 0) {
- tbd = Paint::kBackward_TextBufferDirection;
+ forwardTextDirection = false;
count = -count;
}
else {
- tbd = Paint::kForward_TextBufferDirection;
+ forwardTextDirection = true;
}
if ((index < 0) || (index + count > env->GetArrayLength(jtext))) {
@@ -873,7 +896,7 @@
const jchar* text = env->GetCharArrayElements(jtext, NULL);
count = breakText(env, *paint, typeface, text + index, count, maxWidth,
- bidiFlags, jmeasuredWidth, tbd);
+ bidiFlags, jmeasuredWidth, forwardTextDirection);
env->ReleaseCharArrayElements(jtext, const_cast<jchar*>(text),
JNI_ABORT);
return count;
@@ -886,13 +909,9 @@
Paint* paint = reinterpret_cast<Paint*>(paintHandle);
TypefaceImpl* typeface = reinterpret_cast<TypefaceImpl*>(typefaceHandle);
- Paint::TextBufferDirection tbd = forwards ?
- Paint::kForward_TextBufferDirection :
- Paint::kBackward_TextBufferDirection;
-
int count = env->GetStringLength(jtext);
const jchar* text = env->GetStringChars(jtext, NULL);
- count = breakText(env, *paint, typeface, text, count, maxWidth, bidiFlags, jmeasuredWidth, tbd);
+ count = breakText(env, *paint, typeface, text, count, maxWidth, bidiFlags, jmeasuredWidth, forwards);
env->ReleaseStringChars(jtext, text);
return count;
}
@@ -1021,32 +1040,37 @@
{"native_hasShadowLayer", "!(J)Z", (void*)PaintGlue::hasShadowLayer}
};
+static jclass makeGlobalRef(JNIEnv* env, const char classname[])
+{
+ jclass c = env->FindClass(classname);
+ SkASSERT(c);
+ return (jclass) env->NewGlobalRef(c);
+}
+
static jfieldID req_fieldID(jfieldID id) {
SkASSERT(id);
return id;
}
int register_android_graphics_Paint(JNIEnv* env) {
- gFontMetrics_class = env->FindClass("android/graphics/Paint$FontMetrics");
- SkASSERT(gFontMetrics_class);
- gFontMetrics_class = (jclass)env->NewGlobalRef(gFontMetrics_class);
-
+ gFontMetrics_class = makeGlobalRef(env, "android/graphics/Paint$FontMetrics");
gFontMetrics_fieldID.top = req_fieldID(env->GetFieldID(gFontMetrics_class, "top", "F"));
gFontMetrics_fieldID.ascent = req_fieldID(env->GetFieldID(gFontMetrics_class, "ascent", "F"));
gFontMetrics_fieldID.descent = req_fieldID(env->GetFieldID(gFontMetrics_class, "descent", "F"));
gFontMetrics_fieldID.bottom = req_fieldID(env->GetFieldID(gFontMetrics_class, "bottom", "F"));
gFontMetrics_fieldID.leading = req_fieldID(env->GetFieldID(gFontMetrics_class, "leading", "F"));
- gFontMetricsInt_class = env->FindClass("android/graphics/Paint$FontMetricsInt");
- SkASSERT(gFontMetricsInt_class);
- gFontMetricsInt_class = (jclass)env->NewGlobalRef(gFontMetricsInt_class);
-
+ gFontMetricsInt_class = makeGlobalRef(env, "android/graphics/Paint$FontMetricsInt");
gFontMetricsInt_fieldID.top = req_fieldID(env->GetFieldID(gFontMetricsInt_class, "top", "I"));
gFontMetricsInt_fieldID.ascent = req_fieldID(env->GetFieldID(gFontMetricsInt_class, "ascent", "I"));
gFontMetricsInt_fieldID.descent = req_fieldID(env->GetFieldID(gFontMetricsInt_class, "descent", "I"));
gFontMetricsInt_fieldID.bottom = req_fieldID(env->GetFieldID(gFontMetricsInt_class, "bottom", "I"));
gFontMetricsInt_fieldID.leading = req_fieldID(env->GetFieldID(gFontMetricsInt_class, "leading", "I"));
+ gPaint_class = makeGlobalRef(env, "android/graphics/Paint");
+ gPaint_nativeInstanceID = req_fieldID(env->GetFieldID(gPaint_class, "mNativePaint", "J"));
+ gPaint_nativeTypefaceID = req_fieldID(env->GetFieldID(gPaint_class, "mNativeTypeface", "J"));
+
int result = AndroidRuntime::registerNativeMethods(env, "android/graphics/Paint", methods,
sizeof(methods) / sizeof(methods[0]));
return result;
diff --git a/core/jni/android/graphics/Picture.cpp b/core/jni/android/graphics/Picture.cpp
index 630999c..d048a29 100644
--- a/core/jni/android/graphics/Picture.cpp
+++ b/core/jni/android/graphics/Picture.cpp
@@ -93,8 +93,10 @@
} else if (NULL != mPicture.get()) {
mPicture->serialize(stream);
} else {
- SkPicture empty;
- empty.serialize(stream);
+ SkPictureRecorder recorder;
+ recorder.beginRecording(0, 0);
+ SkAutoTUnref<SkPicture> empty(recorder.endRecording());
+ empty->serialize(stream);
}
}
diff --git a/core/jni/android/graphics/Shader.cpp b/core/jni/android/graphics/Shader.cpp
index 6146fff..606717b 100644
--- a/core/jni/android/graphics/Shader.cpp
+++ b/core/jni/android/graphics/Shader.cpp
@@ -8,7 +8,6 @@
#include "SkTemplates.h"
#include "SkXfermode.h"
-#include <SkiaShader.h>
#include <Caches.h>
using namespace android::uirenderer;
@@ -56,18 +55,31 @@
SkSafeUnref(shader);
}
-static void Shader_setLocalMatrix(JNIEnv* env, jobject o, jlong shaderHandle, jlong matrixHandle)
+static jlong Shader_setLocalMatrix(JNIEnv* env, jobject o, jlong shaderHandle, jlong matrixHandle)
{
- SkShader* shader = reinterpret_cast<SkShader*>(shaderHandle);
+ // ensure we have a valid matrix to use
const SkMatrix* matrix = reinterpret_cast<SkMatrix*>(matrixHandle);
- if (shader) {
- if (matrix) {
- shader->setLocalMatrix(*matrix);
- } else {
- shader->resetLocalMatrix();
- }
- shader->setGenerationID(shader->getGenerationID() + 1);
+ if (NULL == matrix) {
+ matrix = &SkMatrix::I();
}
+
+ // The current shader will no longer need a direct reference owned by Shader.java
+ // as all the data needed is contained within the newly created LocalMatrixShader.
+ SkASSERT(shaderHandle);
+ SkAutoTUnref<SkShader> currentShader(reinterpret_cast<SkShader*>(shaderHandle));
+
+ SkMatrix currentMatrix;
+ SkAutoTUnref<SkShader> baseShader(currentShader->refAsALocalMatrixShader(¤tMatrix));
+ if (baseShader.get()) {
+ // if the matrices are same then there is no need to allocate a new
+ // shader that is identical to the existing one.
+ if (currentMatrix == *matrix) {
+ return reinterpret_cast<jlong>(currentShader.detach());
+ }
+ return reinterpret_cast<jlong>(SkShader::CreateLocalMatrixShader(baseShader, *matrix));
+ }
+
+ return reinterpret_cast<jlong>(SkShader::CreateLocalMatrixShader(currentShader, *matrix));
}
///////////////////////////////////////////////////////////////////////////////////////////////
@@ -238,7 +250,7 @@
static JNINativeMethod gShaderMethods[] = {
{ "nativeDestructor", "(J)V", (void*)Shader_destructor },
- { "nativeSetLocalMatrix", "(JJ)V", (void*)Shader_setLocalMatrix }
+ { "nativeSetLocalMatrix", "(JJ)J", (void*)Shader_setLocalMatrix }
};
static JNINativeMethod gBitmapShaderMethods[] = {
diff --git a/core/jni/android/graphics/YuvToJpegEncoder.cpp b/core/jni/android/graphics/YuvToJpegEncoder.cpp
index 6591d60..9b2e4b5 100644
--- a/core/jni/android/graphics/YuvToJpegEncoder.cpp
+++ b/core/jni/android/graphics/YuvToJpegEncoder.cpp
@@ -236,6 +236,7 @@
env->ReleaseByteArrayElements(inYuv, yuv, 0);
env->ReleaseIntArrayElements(offsets, imgOffsets, 0);
env->ReleaseIntArrayElements(strides, imgStrides, 0);
+ delete strm;
return result;
}
///////////////////////////////////////////////////////////////////////////////
diff --git a/core/jni/android_hardware_camera2_DngCreator.cpp b/core/jni/android_hardware_camera2_DngCreator.cpp
index 31c7b9f..533313a 100644
--- a/core/jni/android_hardware_camera2_DngCreator.cpp
+++ b/core/jni/android_hardware_camera2_DngCreator.cpp
@@ -1278,7 +1278,7 @@
}
BAIL_IF_INVALID(writer->addEntry(TAG_CAMERACALIBRATION2, entry2.count,
- calibrationTransform1, TIFF_IFD_0), env, TAG_CAMERACALIBRATION2, writer);
+ calibrationTransform2, TIFF_IFD_0), env, TAG_CAMERACALIBRATION2, writer);
}
}
diff --git a/core/jni/android_net_LocalSocketImpl.cpp b/core/jni/android_net_LocalSocketImpl.cpp
index 98f4bed..a408a96 100644
--- a/core/jni/android_net_LocalSocketImpl.cpp
+++ b/core/jni/android_net_LocalSocketImpl.cpp
@@ -57,7 +57,7 @@
fd = jniGetFDFromFileDescriptor(env, fileDescriptor);
- if (env->ExceptionOccurred() != NULL) {
+ if (env->ExceptionCheck()) {
return;
}
@@ -95,7 +95,7 @@
fd = jniGetFDFromFileDescriptor(env, fileDescriptor);
- if (env->ExceptionOccurred() != NULL) {
+ if (env->ExceptionCheck()) {
return;
}
@@ -118,7 +118,7 @@
fd = jniGetFDFromFileDescriptor(env, fileDescriptor);
- if (env->ExceptionOccurred() != NULL) {
+ if (env->ExceptionCheck()) {
return;
}
@@ -154,7 +154,7 @@
fd = jniGetFDFromFileDescriptor(env, fileDescriptor);
- if (env->ExceptionOccurred() != NULL) {
+ if (env->ExceptionCheck()) {
return NULL;
}
@@ -184,7 +184,7 @@
fd = jniGetFDFromFileDescriptor(env, fileDescriptor);
- if (env->ExceptionOccurred() != NULL) {
+ if (env->ExceptionCheck()) {
return;
}
@@ -246,7 +246,7 @@
fd = jniGetFDFromFileDescriptor(env, fileDescriptor);
- if (env->ExceptionOccurred() != NULL) {
+ if (env->ExceptionCheck()) {
return 0;
}
@@ -293,7 +293,7 @@
fd = jniGetFDFromFileDescriptor(env, fileDescriptor);
- if (env->ExceptionOccurred() != NULL) {
+ if (env->ExceptionCheck()) {
return;
}
@@ -353,7 +353,7 @@
fd = jniGetFDFromFileDescriptor(env, fileDescriptor);
- if (env->ExceptionOccurred() != NULL) {
+ if (env->ExceptionCheck()) {
return (jint)-1;
}
@@ -378,7 +378,7 @@
fd = jniGetFDFromFileDescriptor(env, fileDescriptor);
- if (env->ExceptionOccurred() != NULL) {
+ if (env->ExceptionCheck()) {
return (jint)-1;
}
@@ -459,20 +459,20 @@
jobject fdObject
= jniCreateFileDescriptor(env, pDescriptors[i]);
- if (env->ExceptionOccurred() != NULL) {
+ if (env->ExceptionCheck()) {
return -1;
}
env->SetObjectArrayElement(fdArray, i, fdObject);
- if (env->ExceptionOccurred() != NULL) {
+ if (env->ExceptionCheck()) {
return -1;
}
}
env->SetObjectField(thisJ, field_inboundFileDescriptors, fdArray);
- if (env->ExceptionOccurred() != NULL) {
+ if (env->ExceptionCheck()) {
return -1;
}
}
@@ -558,7 +558,7 @@
= (jobjectArray)env->GetObjectField(
object, field_outboundFileDescriptors);
- if (env->ExceptionOccurred() != NULL) {
+ if (env->ExceptionCheck()) {
return -1;
}
@@ -570,18 +570,18 @@
// Add any pending outbound file descriptors to the message
if (outboundFds != NULL) {
- if (env->ExceptionOccurred() != NULL) {
+ if (env->ExceptionCheck()) {
return -1;
}
for (int i = 0; i < countFds; i++) {
jobject fdObject = env->GetObjectArrayElement(outboundFds, i);
- if (env->ExceptionOccurred() != NULL) {
+ if (env->ExceptionCheck()) {
return -1;
}
fds[i] = jniGetFDFromFileDescriptor(env, fdObject);
- if (env->ExceptionOccurred() != NULL) {
+ if (env->ExceptionCheck()) {
return -1;
}
}
@@ -638,7 +638,7 @@
fd = jniGetFDFromFileDescriptor(env, fileDescriptor);
- if (env->ExceptionOccurred() != NULL) {
+ if (env->ExceptionCheck()) {
return (jint)0;
}
@@ -683,7 +683,7 @@
fd = jniGetFDFromFileDescriptor(env, fileDescriptor);
- if (env->ExceptionOccurred() != NULL) {
+ if (env->ExceptionCheck()) {
return (jint)-1;
}
@@ -717,7 +717,7 @@
fd = jniGetFDFromFileDescriptor(env, fileDescriptor);
- if (env->ExceptionOccurred() != NULL) {
+ if (env->ExceptionCheck()) {
return;
}
@@ -745,7 +745,7 @@
fd = jniGetFDFromFileDescriptor(env, fileDescriptor);
- if (env->ExceptionOccurred() != NULL) {
+ if (env->ExceptionCheck()) {
return;
}
@@ -777,7 +777,7 @@
fd = jniGetFDFromFileDescriptor(env, fileDescriptor);
- if (env->ExceptionOccurred() != NULL) {
+ if (env->ExceptionCheck()) {
return NULL;
}
@@ -816,7 +816,7 @@
fd = jniGetFDFromFileDescriptor(env, fileDescriptor);
- if (env->ExceptionOccurred() != NULL) {
+ if (env->ExceptionCheck()) {
return NULL;
}
diff --git a/core/jni/android_os_MessageQueue.cpp b/core/jni/android_os_MessageQueue.cpp
index a8ed895..15d62a2 100644
--- a/core/jni/android_os_MessageQueue.cpp
+++ b/core/jni/android_os_MessageQueue.cpp
@@ -54,8 +54,8 @@
}
bool MessageQueue::raiseAndClearException(JNIEnv* env, const char* msg) {
- jthrowable exceptionObj = env->ExceptionOccurred();
- if (exceptionObj) {
+ if (env->ExceptionCheck()) {
+ jthrowable exceptionObj = env->ExceptionOccurred();
env->ExceptionClear();
raiseException(env, msg, exceptionObj);
env->DeleteLocalRef(exceptionObj);
diff --git a/core/jni/android_os_SELinux.cpp b/core/jni/android_os_SELinux.cpp
index ffa569e..c282549 100644
--- a/core/jni/android_os_SELinux.cpp
+++ b/core/jni/android_os_SELinux.cpp
@@ -97,7 +97,7 @@
}
int fd = jniGetFDFromFileDescriptor(env, fileDescriptor);
- if (env->ExceptionOccurred() != NULL) {
+ if (env->ExceptionCheck()) {
ALOGE("getPeerCon => getFD for %p failed", fileDescriptor);
return NULL;
}
diff --git a/core/jni/android_server_FingerprintManager.cpp b/core/jni/android_server_FingerprintManager.cpp
index b174d1b..4e2d93e 100644
--- a/core/jni/android_server_FingerprintManager.cpp
+++ b/core/jni/android_server_FingerprintManager.cpp
@@ -184,7 +184,7 @@
// TODO: clean up void methods
static const JNINativeMethod g_methods[] = {
{ "nativeEnroll", "(I)I", (void*)nativeEnroll },
- { "nativeEnrollCancel", "()I", (void*)nativeEnroll },
+ { "nativeEnrollCancel", "()I", (void*)nativeEnrollCancel },
{ "nativeRemove", "(I)I", (void*)nativeRemove },
{ "nativeOpenHal", "()I", (void*)nativeOpenHal },
{ "nativeCloseHal", "()I", (void*)nativeCloseHal },
diff --git a/core/jni/android_server_NetworkManagementSocketTagger.cpp b/core/jni/android_server_NetworkManagementSocketTagger.cpp
index 7e12b1e..ca21fd7 100644
--- a/core/jni/android_server_NetworkManagementSocketTagger.cpp
+++ b/core/jni/android_server_NetworkManagementSocketTagger.cpp
@@ -35,7 +35,7 @@
jint tagNum, jint uid) {
int userFd = jniGetFDFromFileDescriptor(env, fileDescriptor);
- if (env->ExceptionOccurred() != NULL) {
+ if (env->ExceptionCheck()) {
ALOGE("Can't get FileDescriptor num");
return (jint)-1;
}
@@ -51,7 +51,7 @@
jobject fileDescriptor) {
int userFd = jniGetFDFromFileDescriptor(env, fileDescriptor);
- if (env->ExceptionOccurred() != NULL) {
+ if (env->ExceptionCheck()) {
ALOGE("Can't get FileDescriptor num");
return (jint)-1;
}
diff --git a/core/jni/android_text_StaticLayout.cpp b/core/jni/android_text_StaticLayout.cpp
index 9e20d18..3ce7b0e 100644
--- a/core/jni/android_text_StaticLayout.cpp
+++ b/core/jni/android_text_StaticLayout.cpp
@@ -24,16 +24,421 @@
#include "ScopedPrimitiveArray.h"
#include "JNIHelp.h"
#include <android_runtime/AndroidRuntime.h>
+#include <cstdint>
#include <vector>
+#include <list>
+#include <algorithm>
namespace android {
+struct JLineBreaksID {
+ jfieldID breaks;
+ jfieldID widths;
+ jfieldID flags;
+};
+
+static jclass gLineBreaks_class;
+static JLineBreaksID gLineBreaks_fieldID;
+
+static const int CHAR_SPACE = 0x20;
+static const int CHAR_TAB = 0x09;
+static const int CHAR_NEWLINE = 0x0a;
+static const int CHAR_ZWSP = 0x200b;
+
+class TabStops {
+ public:
+ // specified stops must be a sorted array (allowed to be null)
+ TabStops(JNIEnv* env, jintArray stops, jint defaultTabWidth) :
+ mStops(env), mTabWidth(defaultTabWidth) {
+ if (stops != NULL) {
+ mStops.reset(stops);
+ mNumStops = mStops.size();
+ } else {
+ mNumStops = 0;
+ }
+ }
+ float width(float widthSoFar) const {
+ const jint* mStopsArray = mStops.get();
+ for (int i = 0; i < mNumStops; i++) {
+ if (mStopsArray[i] > widthSoFar) {
+ return mStopsArray[i];
+ }
+ }
+ // find the next tabstop after widthSoFar
+ return static_cast<int>((widthSoFar + mTabWidth) / mTabWidth) * mTabWidth;
+ }
+ private:
+ ScopedIntArrayRO mStops;
+ const int mTabWidth;
+ int mNumStops;
+
+ // disable copying and assignment
+ TabStops(const TabStops&);
+ void operator=(const TabStops&);
+};
+
+enum PrimitiveType {
+ kPrimitiveType_Box,
+ kPrimitiveType_Glue,
+ kPrimitiveType_Penalty,
+ kPrimitiveType_Variable,
+ kPrimitiveType_Wordbreak
+};
+
+static const float PENALTY_INFINITY = 1e7; // forced non-break, negative infinity is forced break
+
+struct Primitive {
+ PrimitiveType type;
+ int location;
+ // 'Box' has width
+ // 'Glue' has width
+ // 'Penalty' has width and penalty
+ // 'Variable' has tabStop
+ // 'Wordbreak' has penalty
+ union {
+ struct {
+ float width;
+ float penalty;
+ };
+ const TabStops* tabStop;
+ };
+};
+
+class LineWidth {
+ public:
+ LineWidth(float firstWidth, int firstWidthLineCount, float restWidth) :
+ mFirstWidth(firstWidth), mFirstWidthLineCount(firstWidthLineCount),
+ mRestWidth(restWidth) {}
+ float getLineWidth(int line) const {
+ return (line < mFirstWidthLineCount) ? mFirstWidth : mRestWidth;
+ }
+ private:
+ const float mFirstWidth;
+ const int mFirstWidthLineCount;
+ const float mRestWidth;
+};
+
+class LineBreaker {
+ public:
+ LineBreaker(const std::vector<Primitive>& primitives,
+ const LineWidth& lineWidth) :
+ mPrimitives(primitives), mLineWidth(lineWidth) {}
+ virtual ~LineBreaker() {}
+ virtual void computeBreaks(std::vector<int>* breaks, std::vector<float>* widths,
+ std::vector<unsigned char>* flags) const = 0;
+ protected:
+ const std::vector<Primitive>& mPrimitives;
+ const LineWidth& mLineWidth;
+};
+
+class OptimizingLineBreaker : public LineBreaker {
+ public:
+ OptimizingLineBreaker(const std::vector<Primitive>& primitives, const LineWidth& lineWidth) :
+ LineBreaker(primitives, lineWidth) {}
+ void computeBreaks(std::vector<int>* breaks, std::vector<float>* widths,
+ std::vector<unsigned char>* flags) const {
+ int numBreaks = mPrimitives.size();
+ Node* opt = new Node[numBreaks];
+ opt[0].prev = -1;
+ opt[0].prevCount = 0;
+ opt[0].width = 0;
+ opt[0].demerits = 0;
+ opt[0].flags = false;
+ opt[numBreaks - 1].prev = -1;
+ opt[numBreaks - 1].prevCount = 0;
+
+ std::list<int> active;
+ active.push_back(0);
+ int lastBreak = 0;
+ for (int i = 0; i < numBreaks; i++) {
+ const Primitive& p = mPrimitives[i];
+ if (p.type == kPrimitiveType_Penalty) {
+ const bool finalBreak = (i + 1 == numBreaks);
+ bool breakFound = false;
+ Node bestBreak;
+ for (std::list<int>::iterator it = active.begin(); it != active.end(); /* incrementing done in loop */) {
+ const int pos = *it;
+ bool flags;
+ float width, printedWidth;
+ const int lines = opt[pos].prevCount;
+ const float maxWidth = mLineWidth.getLineWidth(lines);
+ // we have to compute metrics every time --
+ // we can't really precompute this stuff and just deal with breaks
+ // because of the way tab characters work, this makes it computationally
+ // harder, but this way, we can still optimize while treating tab characters
+ // correctly
+ computeMetrics(pos, i, &width, &printedWidth, &flags);
+ if (printedWidth <= maxWidth) {
+ float demerits = computeDemerits(maxWidth, printedWidth,
+ finalBreak, p.penalty) + opt[pos].demerits;
+ if (!breakFound || demerits < bestBreak.demerits) {
+ bestBreak.prev = pos;
+ bestBreak.prevCount = opt[pos].prevCount + 1;
+ bestBreak.demerits = demerits;
+ bestBreak.width = printedWidth;
+ bestBreak.flags = flags;
+ breakFound = true;
+ }
+ ++it;
+ } else {
+ active.erase(it++); // safe to delete like this
+ }
+ }
+ if (p.penalty == -PENALTY_INFINITY) {
+ active.clear();
+ }
+ if (breakFound) {
+ opt[i] = bestBreak;
+ active.push_back(i);
+ lastBreak = i;
+ }
+ if (active.empty()) {
+ // we can't give up!
+ float width, printedWidth;
+ bool flags;
+ const int lines = opt[lastBreak].prevCount;
+ const float maxWidth = mLineWidth.getLineWidth(lines);
+ const int breakIndex = desperateBreak(lastBreak, numBreaks, maxWidth, &width, &printedWidth, &flags);
+
+ opt[breakIndex].prev = lastBreak;
+ opt[breakIndex].prevCount = lines + 1;
+ opt[breakIndex].demerits = 0; // doesn't matter, it's the only one
+ opt[breakIndex].width = width;
+ opt[breakIndex].flags = flags;
+
+ active.push_back(breakIndex);
+ lastBreak = breakIndex;
+ i = breakIndex; // incremented by i++
+ }
+ }
+ }
+
+ int idx = numBreaks - 1;
+ int count = opt[idx].prevCount;
+ breaks->resize(count);
+ widths->resize(count);
+ flags->resize(count);
+ while (opt[idx].prev != -1) {
+ --count;
+
+ (*breaks)[count] = mPrimitives[idx].location;
+ (*widths)[count] = opt[idx].width;
+ (*flags)[count] = opt[idx].flags;
+
+ idx = opt[idx].prev;
+ }
+ delete[] opt;
+ }
+ private:
+ inline void computeMetrics(int start, int end, float* width, float* printedWidth, bool* flags) const {
+ bool f = false;
+ float w = 0, pw = 0;
+ for (int i = start; i < end; i++) {
+ const Primitive& p = mPrimitives[i];
+ if (p.type == kPrimitiveType_Box || p.type == kPrimitiveType_Glue) {
+ w += p.width;
+ if (p.type == kPrimitiveType_Box) {
+ pw = w;
+ }
+ } else if (p.type == kPrimitiveType_Variable) {
+ w = p.tabStop->width(w);
+ f = true;
+ }
+ }
+ *width = w;
+ *printedWidth = pw;
+ *flags = f;
+ }
+
+ inline float computeDemerits(float maxWidth, float width, bool finalBreak, float penalty) const {
+ float deviation = finalBreak ? 0 : maxWidth - width;
+ return (deviation * deviation) + penalty;
+ }
+
+ // returns end pos (chosen break), -1 if fail
+ inline int desperateBreak(int start, int limit, float maxWidth, float* width, float* printedWidth, bool* flags) const {
+ float w = 0, pw = 0;
+ bool breakFound = false;
+ int breakIndex = 0, firstTabIndex = INT_MAX;
+ float breakWidth, breakPrintedWidth;
+ for (int i = start; i < limit; i++) {
+ const Primitive& p = mPrimitives[i];
+
+ if (p.type == kPrimitiveType_Box || p.type == kPrimitiveType_Glue) {
+ w += p.width;
+ if (p.type == kPrimitiveType_Box) {
+ pw = w;
+ }
+ } else if (p.type == kPrimitiveType_Variable) {
+ w = p.tabStop->width(w);
+ firstTabIndex = std::min(firstTabIndex, i);
+ }
+
+ if (pw > maxWidth) {
+ if (breakFound) {
+ break;
+ } else {
+ // no choice, keep going
+ }
+ }
+
+ // must make progress
+ if (i > start && (p.type == kPrimitiveType_Penalty || p.type == kPrimitiveType_Wordbreak)) {
+ breakFound = true;
+ breakIndex = i;
+ breakWidth = w;
+ breakPrintedWidth = pw;
+ }
+ }
+
+ if (breakFound) {
+ *width = w;
+ *printedWidth = pw;
+ *flags = (start <= firstTabIndex && firstTabIndex < breakIndex);
+ return breakIndex;
+ } else {
+ return -1;
+ }
+ }
+
+ struct Node {
+ int prev; // set to sentinel value (-1) for initial node
+ int prevCount; // number of breaks so far
+ float demerits;
+ float width;
+ bool flags;
+ };
+};
+
+class GreedyLineBreaker : public LineBreaker {
+ public:
+ GreedyLineBreaker(const std::vector<Primitive>& primitives, const LineWidth& lineWidth) :
+ LineBreaker(primitives, lineWidth) {}
+ void computeBreaks(std::vector<int>* breaks, std::vector<float>* widths,
+ std::vector<unsigned char>* flags) const {
+ int lineNum = 0;
+ float width = 0, printedWidth = 0;
+ bool breakFound = false, goodBreakFound = false;
+ int breakIndex = 0, goodBreakIndex = 0;
+ float breakWidth = 0, goodBreakWidth = 0;
+ int firstTabIndex = INT_MAX;
+
+ float maxWidth = mLineWidth.getLineWidth(lineNum);
+
+ const int numPrimitives = mPrimitives.size();
+ // greedily fit as many characters as possible on each line
+ // loop over all primitives, and choose the best break point
+ // (if possible, a break point without splitting a word)
+ // after going over the maximum length
+ for (int i = 0; i < numPrimitives; i++) {
+ const Primitive& p = mPrimitives[i];
+
+ // update the current line width
+ if (p.type == kPrimitiveType_Box || p.type == kPrimitiveType_Glue) {
+ width += p.width;
+ if (p.type == kPrimitiveType_Box) {
+ printedWidth = width;
+ }
+ } else if (p.type == kPrimitiveType_Variable) {
+ width = p.tabStop->width(width);
+ // keep track of first tab character in the region we are examining
+ // so we can determine whether or not a line contains a tab
+ firstTabIndex = std::min(firstTabIndex, i);
+ }
+
+ // find the best break point for the characters examined so far
+ if (printedWidth > maxWidth) {
+ if (breakFound || goodBreakFound) {
+ if (goodBreakFound) {
+ // a true line break opportunity existed in the characters examined so far,
+ // so there is no need to split a word
+ i = goodBreakIndex; // no +1 because of i++
+ lineNum++;
+ maxWidth = mLineWidth.getLineWidth(lineNum);
+ breaks->push_back(mPrimitives[goodBreakIndex].location);
+ widths->push_back(goodBreakWidth);
+ flags->push_back(firstTabIndex < goodBreakIndex);
+ firstTabIndex = SIZE_MAX;
+ } else {
+ // must split a word because there is no other option
+ i = breakIndex; // no +1 because of i++
+ lineNum++;
+ maxWidth = mLineWidth.getLineWidth(lineNum);
+ breaks->push_back(mPrimitives[breakIndex].location);
+ widths->push_back(breakWidth);
+ flags->push_back(firstTabIndex < breakIndex);
+ firstTabIndex = SIZE_MAX;
+ }
+ printedWidth = width = 0;
+ goodBreakFound = breakFound = false;
+ goodBreakWidth = breakWidth = 0;
+ continue;
+ } else {
+ // no choice, keep going... must make progress by putting at least one
+ // character on a line, even if part of that character is cut off --
+ // there is no other option
+ }
+ }
+
+ // update possible break points
+ if (p.type == kPrimitiveType_Penalty && p.penalty < PENALTY_INFINITY) {
+ // this does not handle penalties with width
+
+ // handle forced line break
+ if (p.penalty == -PENALTY_INFINITY) {
+ lineNum++;
+ maxWidth = mLineWidth.getLineWidth(lineNum);
+ breaks->push_back(p.location);
+ widths->push_back(printedWidth);
+ flags->push_back(firstTabIndex < i);
+ firstTabIndex = SIZE_MAX;
+ printedWidth = width = 0;
+ goodBreakFound = breakFound = false;
+ goodBreakWidth = breakWidth = 0;
+ continue;
+ }
+ if (i > breakIndex && (printedWidth <= maxWidth || breakFound == false)) {
+ breakFound = true;
+ breakIndex = i;
+ breakWidth = printedWidth;
+ }
+ if (i > goodBreakIndex && printedWidth <= maxWidth) {
+ goodBreakFound = true;
+ goodBreakIndex = i;
+ goodBreakWidth = printedWidth;
+ }
+ } else if (p.type == kPrimitiveType_Wordbreak) {
+ // only do this if necessary -- we don't want to break words
+ // when possible, but sometimes it is unavoidable
+ if (i > breakIndex && (printedWidth <= maxWidth || breakFound == false)) {
+ breakFound = true;
+ breakIndex = i;
+ breakWidth = printedWidth;
+ }
+ }
+ }
+
+ if (breakFound || goodBreakFound) {
+ // output last break if there are more characters to output
+ if (goodBreakFound) {
+ breaks->push_back(mPrimitives[goodBreakIndex].location);
+ widths->push_back(goodBreakWidth);
+ flags->push_back(firstTabIndex < goodBreakIndex);
+ } else {
+ breaks->push_back(mPrimitives[breakIndex].location);
+ widths->push_back(breakWidth);
+ flags->push_back(firstTabIndex < breakIndex);
+ }
+ }
+ }
+};
+
class ScopedBreakIterator {
public:
- ScopedBreakIterator(JNIEnv* env, BreakIterator* breakIterator, jcharArray inputText,
- jint length) : mBreakIterator(breakIterator), mChars(env, inputText) {
+ ScopedBreakIterator(JNIEnv* env, BreakIterator* breakIterator, const jchar* inputText,
+ jint length) : mBreakIterator(breakIterator), mChars(inputText) {
UErrorCode status = U_ZERO_ERROR;
- mUText = utext_openUChars(NULL, mChars.get(), length, &status);
+ mUText = utext_openUChars(NULL, mChars, length, &status);
if (mUText == NULL) {
return;
}
@@ -51,7 +456,7 @@
}
private:
BreakIterator* mBreakIterator;
- ScopedCharArrayRO mChars;
+ const jchar* mChars;
UText* mUText;
// disable copying and assignment
@@ -59,11 +464,83 @@
void operator=(const ScopedBreakIterator&);
};
-static jintArray nLineBreakOpportunities(JNIEnv* env, jclass, jstring javaLocaleName,
- jcharArray inputText, jint length,
- jintArray recycle) {
+static jint recycleCopy(JNIEnv* env, jobject recycle, jintArray recycleBreaks,
+ jfloatArray recycleWidths, jbooleanArray recycleFlags,
+ jint recycleLength, const std::vector<jint>& breaks,
+ const std::vector<jfloat>& widths, const std::vector<jboolean>& flags) {
+ int bufferLength = breaks.size();
+ if (recycleLength < bufferLength) {
+ // have to reallocate buffers
+ recycleBreaks = env->NewIntArray(bufferLength);
+ recycleWidths = env->NewFloatArray(bufferLength);
+ recycleFlags = env->NewBooleanArray(bufferLength);
+
+ env->SetObjectField(recycle, gLineBreaks_fieldID.breaks, recycleBreaks);
+ env->SetObjectField(recycle, gLineBreaks_fieldID.widths, recycleWidths);
+ env->SetObjectField(recycle, gLineBreaks_fieldID.flags, recycleFlags);
+ }
+ // copy data
+ env->SetIntArrayRegion(recycleBreaks, 0, breaks.size(), &breaks.front());
+ env->SetFloatArrayRegion(recycleWidths, 0, widths.size(), &widths.front());
+ env->SetBooleanArrayRegion(recycleFlags, 0, flags.size(), &flags.front());
+
+ return bufferLength;
+}
+
+void computePrimitives(const jchar* textArr, const jfloat* widthsArr, jint length, const std::vector<int>& breaks,
+ const TabStops& tabStopCalculator, std::vector<Primitive>* primitives) {
+ int breaksSize = breaks.size();
+ int breakIndex = 0;
+ Primitive p;
+ for (int i = 0; i < length; i++) {
+ p.location = i;
+ jchar c = textArr[i];
+ if (c == CHAR_SPACE || c == CHAR_ZWSP) {
+ p.type = kPrimitiveType_Glue;
+ p.width = widthsArr[i];
+ primitives->push_back(p);
+ } else if (c == CHAR_TAB) {
+ p.type = kPrimitiveType_Variable;
+ p.tabStop = &tabStopCalculator; // shared between all variable primitives
+ primitives->push_back(p);
+ } else if (c != CHAR_NEWLINE) {
+ while (breakIndex < breaksSize && breaks[breakIndex] < i) breakIndex++;
+ p.width = 0;
+ if (breakIndex < breaksSize && breaks[breakIndex] == i) {
+ p.type = kPrimitiveType_Penalty;
+ p.penalty = 0;
+ } else {
+ p.type = kPrimitiveType_Wordbreak;
+ }
+ if (widthsArr[i] != 0) {
+ primitives->push_back(p);
+ }
+
+ p.type = kPrimitiveType_Box;
+ p.width = widthsArr[i];
+ primitives->push_back(p);
+ }
+ }
+ // final break at end of everything
+ p.location = length;
+ p.type = kPrimitiveType_Penalty;
+ p.width = 0;
+ p.penalty = -PENALTY_INFINITY;
+ primitives->push_back(p);
+}
+
+static jint nComputeLineBreaks(JNIEnv* env, jclass, jstring javaLocaleName,
+ jcharArray inputText, jfloatArray widths, jint length,
+ jfloat firstWidth, jint firstWidthLineLimit, jfloat restWidth,
+ jintArray variableTabStops, jint defaultTabStop, jboolean optimize,
+ jobject recycle, jintArray recycleBreaks,
+ jfloatArray recycleWidths, jbooleanArray recycleFlags,
+ jint recycleLength) {
jintArray ret;
- std::vector<jint> breaks;
+ std::vector<int> breaks;
+
+ ScopedCharArrayRO textScopedArr(env, inputText);
+ ScopedFloatArrayRO widthsScopedArr(env, widths);
ScopedIcuLocale icuLocale(env, javaLocaleName);
if (icuLocale.valid()) {
@@ -74,35 +551,48 @@
delete it;
}
} else {
- ScopedBreakIterator breakIterator(env, it, inputText, length);
- for (int loc = breakIterator->first(); loc != BreakIterator::DONE;
- loc = breakIterator->next()) {
+ ScopedBreakIterator breakIterator(env, it, textScopedArr.get(), length);
+ int loc = breakIterator->first();
+ while ((loc = breakIterator->next()) != BreakIterator::DONE) {
breaks.push_back(loc);
}
}
}
- breaks.push_back(-1); // sentinel terminal value
+ std::vector<Primitive> primitives;
+ TabStops tabStops(env, variableTabStops, defaultTabStop);
+ computePrimitives(textScopedArr.get(), widthsScopedArr.get(), length, breaks, tabStops, &primitives);
- if (recycle != NULL && static_cast<size_t>(env->GetArrayLength(recycle)) >= breaks.size()) {
- ret = recycle;
+ LineWidth lineWidth(firstWidth, firstWidthLineLimit, restWidth);
+ std::vector<int> computedBreaks;
+ std::vector<float> computedWidths;
+ std::vector<unsigned char> computedFlags;
+
+ if (optimize) {
+ OptimizingLineBreaker breaker(primitives, lineWidth);
+ breaker.computeBreaks(&computedBreaks, &computedWidths, &computedFlags);
} else {
- ret = env->NewIntArray(breaks.size());
+ GreedyLineBreaker breaker(primitives, lineWidth);
+ breaker.computeBreaks(&computedBreaks, &computedWidths, &computedFlags);
}
- if (ret != NULL) {
- env->SetIntArrayRegion(ret, 0, breaks.size(), &breaks.front());
- }
-
- return ret;
+ return recycleCopy(env, recycle, recycleBreaks, recycleWidths, recycleFlags, recycleLength,
+ computedBreaks, computedWidths, computedFlags);
}
static JNINativeMethod gMethods[] = {
- {"nLineBreakOpportunities", "(Ljava/lang/String;[CI[I)[I", (void*) nLineBreakOpportunities}
+ {"nComputeLineBreaks", "(Ljava/lang/String;[C[FIFIF[IIZLandroid/text/StaticLayout$LineBreaks;[I[F[ZI)I", (void*) nComputeLineBreaks}
};
int register_android_text_StaticLayout(JNIEnv* env)
{
+ gLineBreaks_class = reinterpret_cast<jclass>(env->NewGlobalRef(
+ env->FindClass("android/text/StaticLayout$LineBreaks")));
+
+ gLineBreaks_fieldID.breaks = env->GetFieldID(gLineBreaks_class, "breaks", "[I");
+ gLineBreaks_fieldID.widths = env->GetFieldID(gLineBreaks_class, "widths", "[F");
+ gLineBreaks_fieldID.flags = env->GetFieldID(gLineBreaks_class, "flags", "[Z");
+
return AndroidRuntime::registerNativeMethods(env, "android/text/StaticLayout",
gMethods, NELEM(gMethods));
}
diff --git a/core/jni/android_util_AssetManager.cpp b/core/jni/android_util_AssetManager.cpp
index 94098c9..28ee1e4 100644
--- a/core/jni/android_util_AssetManager.cpp
+++ b/core/jni/android_util_AssetManager.cpp
@@ -2088,7 +2088,7 @@
{ "getAssetAllocations", "()Ljava/lang/String;",
(void*) android_content_AssetManager_getAssetAllocations },
{ "getGlobalAssetManagerCount", "()I",
- (void*) android_content_AssetManager_getGlobalAssetCount },
+ (void*) android_content_AssetManager_getGlobalAssetManagerCount },
};
int register_android_content_AssetManager(JNIEnv* env)
diff --git a/core/jni/android_util_Binder.cpp b/core/jni/android_util_Binder.cpp
index e400698..a78c386 100644
--- a/core/jni/android_util_Binder.cpp
+++ b/core/jni/android_util_Binder.cpp
@@ -271,9 +271,9 @@
//printf("\n");
jboolean res = env->CallBooleanMethod(mObject, gBinderOffsets.mExecTransact,
code, reinterpret_cast<jlong>(&data), reinterpret_cast<jlong>(reply), flags);
- jthrowable excep = env->ExceptionOccurred();
- if (excep) {
+ if (env->ExceptionCheck()) {
+ jthrowable excep = env->ExceptionOccurred();
report_exception(env, excep,
"*** Uncaught remote exception! "
"(Exceptions are not yet supported across processes.)");
@@ -291,12 +291,12 @@
set_dalvik_blockguard_policy(env, strict_policy_before);
}
- jthrowable excep2 = env->ExceptionOccurred();
- if (excep2) {
- report_exception(env, excep2,
+ if (env->ExceptionCheck()) {
+ jthrowable excep = env->ExceptionOccurred();
+ report_exception(env, excep,
"*** Uncaught exception in onBinderStrictModePolicyChange");
/* clean up JNI local ref -- we don't return to Java code */
- env->DeleteLocalRef(excep2);
+ env->DeleteLocalRef(excep);
}
// Need to always call through the native implementation of
@@ -398,8 +398,8 @@
env->CallStaticVoidMethod(gBinderProxyOffsets.mClass,
gBinderProxyOffsets.mSendDeathNotice, mObject);
- jthrowable excep = env->ExceptionOccurred();
- if (excep) {
+ if (env->ExceptionCheck()) {
+ jthrowable excep = env->ExceptionOccurred();
report_exception(env, excep,
"*** Uncaught exception returned from death notification!");
}
@@ -1063,16 +1063,9 @@
}
// We only measure binder call durations to potentially log them if
-// we're on the main thread. Unfortunately sim-eng doesn't seem to
-// have gettid, so we just ignore this and don't log if we can't
-// get the thread id.
+// we're on the main thread.
static bool should_time_binder_calls() {
-#ifdef HAVE_GETTID
- return (getpid() == androidGetTid());
-#else
-#warning no gettid(), so not logging Binder calls...
- return false;
-#endif
+ return (getpid() == gettid());
}
static jboolean android_os_BinderProxy_transact(JNIEnv* env, jobject obj,
diff --git a/core/jni/android_util_FileObserver.cpp b/core/jni/android_util_FileObserver.cpp
index 0327d8c..b906cfd 100644
--- a/core/jni/android_util_FileObserver.cpp
+++ b/core/jni/android_util_FileObserver.cpp
@@ -29,7 +29,7 @@
#include <sys/ioctl.h>
#include <errno.h>
-#ifdef HAVE_INOTIFY
+#if defined(__linux__)
#include <sys/inotify.h>
#endif
@@ -39,29 +39,25 @@
static jint android_os_fileobserver_init(JNIEnv* env, jobject object)
{
-#ifdef HAVE_INOTIFY
-
- return (jint)inotify_init();
-
-#else // HAVE_INOTIFY
-
+#if defined(__linux__)
+ return (jint)inotify_init();
+#else
return -1;
-
-#endif // HAVE_INOTIFY
+#endif
}
static void android_os_fileobserver_observe(JNIEnv* env, jobject object, jint fd)
{
-#ifdef HAVE_INOTIFY
-
+#if defined(__linux__)
+
char event_buf[512];
struct inotify_event* event;
-
+
while (1)
{
int event_pos = 0;
int num_bytes = read(fd, event_buf, sizeof(event_buf));
-
+
if (num_bytes < (int)sizeof(*event))
{
if (errno == EINTR)
@@ -70,14 +66,14 @@
ALOGE("***** ERROR! android_os_fileobserver_observe() got a short event!");
return;
}
-
+
while (num_bytes >= (int)sizeof(*event))
{
int event_size;
event = (struct inotify_event *)(event_buf + event_pos);
jstring path = NULL;
-
+
if (event->len > 0)
{
path = env->NewStringUTF(event->name);
@@ -98,37 +94,37 @@
event_pos += event_size;
}
}
-
-#endif // HAVE_INOTIFY
+
+#endif
}
static jint android_os_fileobserver_startWatching(JNIEnv* env, jobject object, jint fd, jstring pathString, jint mask)
{
int res = -1;
-
-#ifdef HAVE_INOTIFY
-
+
+#if defined(__linux__)
+
if (fd >= 0)
{
const char* path = env->GetStringUTFChars(pathString, NULL);
-
+
res = inotify_add_watch(fd, path, mask);
-
+
env->ReleaseStringUTFChars(pathString, path);
}
-#endif // HAVE_INOTIFY
-
+#endif
+
return res;
}
static void android_os_fileobserver_stopWatching(JNIEnv* env, jobject object, jint fd, jint wfd)
{
-#ifdef HAVE_INOTIFY
+#if defined(__linux__)
inotify_rm_watch((int)fd, (uint32_t)wfd);
-#endif // HAVE_INOTIFY
+#endif
}
static JNINativeMethod sMethods[] = {
@@ -137,7 +133,7 @@
{ "observe", "(I)V", (void*)android_os_fileobserver_observe },
{ "startWatching", "(ILjava/lang/String;I)I", (void*)android_os_fileobserver_startWatching },
{ "stopWatching", "(II)V", (void*)android_os_fileobserver_stopWatching }
-
+
};
int register_android_os_FileObserver(JNIEnv* env)
diff --git a/core/jni/android_util_FloatMath.cpp b/core/jni/android_util_FloatMath.cpp
deleted file mode 100644
index 73b7a6f..0000000
--- a/core/jni/android_util_FloatMath.cpp
+++ /dev/null
@@ -1,61 +0,0 @@
-#include "jni.h"
-#include <android_runtime/AndroidRuntime.h>
-#include <math.h>
-#include <float.h>
-#include "SkTypes.h"
-
-class MathUtilsGlue {
-public:
- static float FloorF(JNIEnv* env, jobject clazz, float x) {
- return floorf(x);
- }
-
- static float CeilF(JNIEnv* env, jobject clazz, float x) {
- return ceilf(x);
- }
-
- static float SinF(JNIEnv* env, jobject clazz, float x) {
- return sinf(x);
- }
-
- static float CosF(JNIEnv* env, jobject clazz, float x) {
- return cosf(x);
- }
-
- static float SqrtF(JNIEnv* env, jobject clazz, float x) {
- return sqrtf(x);
- }
-
- static float ExpF(JNIEnv* env, jobject clazz, float x) {
- return expf(x);
- }
-
- static float PowF(JNIEnv* env, jobject clazz, float x, float y) {
- return powf(x, y);
- }
-
- static float HypotF(JNIEnv* env, jobject clazz, float x, float y) {
- return hypotf(x, y);
- }
-};
-
-static JNINativeMethod gMathUtilsMethods[] = {
- {"floor", "(F)F", (void*) MathUtilsGlue::FloorF},
- {"ceil", "(F)F", (void*) MathUtilsGlue::CeilF},
- {"sin", "(F)F", (void*) MathUtilsGlue::SinF},
- {"cos", "(F)F", (void*) MathUtilsGlue::CosF},
- {"sqrt", "(F)F", (void*) MathUtilsGlue::SqrtF},
- {"exp", "(F)F", (void*) MathUtilsGlue::ExpF},
- {"pow", "(FF)F", (void*) MathUtilsGlue::PowF},
- {"hypot", "(FF)F", (void*) MathUtilsGlue::HypotF},
-};
-
-int register_android_util_FloatMath(JNIEnv* env)
-{
- int result = android::AndroidRuntime::registerNativeMethods(env,
- "android/util/FloatMath",
- gMathUtilsMethods,
- SK_ARRAY_COUNT(gMathUtilsMethods));
- return result;
-}
-
diff --git a/core/jni/android_util_Process.cpp b/core/jni/android_util_Process.cpp
index aaa680f..2b0960f 100644
--- a/core/jni/android_util_Process.cpp
+++ b/core/jni/android_util_Process.cpp
@@ -271,7 +271,7 @@
// Establishes the calling thread as illegal to put into the background.
// Typically used only for the system process's main looper.
#if GUARD_THREAD_PRIORITY
- ALOGV("Process.setCanSelfBackground(%d) : tid=%d", bgOk, androidGetTid());
+ ALOGV("Process.setCanSelfBackground(%d) : tid=%d", bgOk, gettid());
{
Mutex::Autolock _l(gKeyCreateMutex);
if (gBgKey == -1) {
@@ -287,7 +287,8 @@
void android_os_Process_setThreadScheduler(JNIEnv* env, jclass clazz,
jint tid, jint policy, jint pri)
{
-#ifdef HAVE_SCHED_SETSCHEDULER
+// linux has sched_setscheduler(), others don't.
+#if defined(__linux__)
struct sched_param param;
param.sched_priority = pri;
int rc = sched_setscheduler(tid, policy, ¶m);
@@ -306,7 +307,7 @@
// if we're putting the current thread into the background, check the TLS
// to make sure this thread isn't guarded. If it is, raise an exception.
if (pri >= ANDROID_PRIORITY_BACKGROUND) {
- if (pid == androidGetTid()) {
+ if (pid == gettid()) {
void* bgOk = pthread_getspecific(gBgKey);
if (bgOk == ((void*)0xbaad)) {
ALOGE("Thread marked fg-only put self in background!");
@@ -333,7 +334,7 @@
void android_os_Process_setCallingThreadPriority(JNIEnv* env, jobject clazz,
jint pri)
{
- android_os_Process_setThreadPriority(env, clazz, androidGetTid(), pri);
+ android_os_Process_setThreadPriority(env, clazz, gettid(), pri);
}
jint android_os_Process_getThreadPriority(JNIEnv* env, jobject clazz,
diff --git a/core/jni/android_view_GLES20Canvas.cpp b/core/jni/android_view_GLES20Canvas.cpp
index b023ebd..78e9253 100644
--- a/core/jni/android_view_GLES20Canvas.cpp
+++ b/core/jni/android_view_GLES20Canvas.cpp
@@ -111,17 +111,17 @@
renderer->insertReorderBarrier(reorderEnable);
}
-static int android_view_GLES20Canvas_prepare(JNIEnv* env, jobject clazz,
+static void android_view_GLES20Canvas_prepare(JNIEnv* env, jobject clazz,
jlong rendererPtr, jboolean opaque) {
DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr);
- return renderer->prepare(opaque);
+ renderer->prepare(opaque);
}
-static int android_view_GLES20Canvas_prepareDirty(JNIEnv* env, jobject clazz,
+static void android_view_GLES20Canvas_prepareDirty(JNIEnv* env, jobject clazz,
jlong rendererPtr, jint left, jint top, jint right, jint bottom,
jboolean opaque) {
DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr);
- return renderer->prepareDirty(left, top, right, bottom, opaque);
+ renderer->prepareDirty(left, top, right, bottom, opaque);
}
static void android_view_GLES20Canvas_finish(JNIEnv* env, jobject clazz,
@@ -152,12 +152,12 @@
// Functor
// ----------------------------------------------------------------------------
-static jint android_view_GLES20Canvas_callDrawGLFunction(JNIEnv* env, jobject clazz,
+static void android_view_GLES20Canvas_callDrawGLFunction(JNIEnv* env, jobject clazz,
jlong rendererPtr, jlong functorPtr) {
DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr);
Functor* functor = reinterpret_cast<Functor*>(functorPtr);
android::uirenderer::Rect dirty;
- return renderer->callDrawGLFunction(functor, dirty);
+ renderer->callDrawGLFunction(functor, dirty);
}
// ----------------------------------------------------------------------------
@@ -588,16 +588,11 @@
// Draw filters
// ----------------------------------------------------------------------------
-static void android_view_GLES20Canvas_setupPaintFilter(JNIEnv* env, jobject clazz,
- jlong rendererPtr, jint clearBits, jint setBits) {
+static void android_view_GLES20Canvas_setDrawFilter(JNIEnv* env, jobject clazz,
+ jlong rendererPtr, jlong filterPtr) {
DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr);
- renderer->setupPaintFilter(clearBits, setBits);
-}
-
-static void android_view_GLES20Canvas_resetPaintFilter(JNIEnv* env, jobject clazz,
- jlong rendererPtr) {
- DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr);
- renderer->resetPaintFilter();
+ SkDrawFilter* filter = reinterpret_cast<SkDrawFilter*>(filterPtr);
+ renderer->setDrawFilter(filter);
}
// ----------------------------------------------------------------------------
@@ -807,18 +802,13 @@
return reinterpret_cast<jlong>(new DisplayListRenderer);
}
-static jint android_view_GLES20Canvas_drawRenderNode(JNIEnv* env,
+static void android_view_GLES20Canvas_drawRenderNode(JNIEnv* env,
jobject clazz, jlong rendererPtr, jlong renderNodePtr,
- jobject dirty, jint flags) {
+ jint flags) {
DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr);
RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
android::uirenderer::Rect bounds;
- status_t status = renderer->drawRenderNode(renderNode, bounds, flags);
- if (status != DrawGlInfo::kStatusDone && dirty != NULL) {
- env->CallVoidMethod(dirty, gRectClassInfo.set,
- int(bounds.left), int(bounds.top), int(bounds.right), int(bounds.bottom));
- }
- return status;
+ renderer->drawRenderNode(renderNode, bounds, flags);
}
// ----------------------------------------------------------------------------
@@ -881,13 +871,13 @@
{ "nSetViewport", "(JII)V", (void*) android_view_GLES20Canvas_setViewport },
{ "nSetHighContrastText","(JZ)V", (void*) android_view_GLES20Canvas_setHighContrastText },
{ "nInsertReorderBarrier","(JZ)V", (void*) android_view_GLES20Canvas_insertReorderBarrier },
- { "nPrepare", "(JZ)I", (void*) android_view_GLES20Canvas_prepare },
- { "nPrepareDirty", "(JIIIIZ)I", (void*) android_view_GLES20Canvas_prepareDirty },
+ { "nPrepare", "(JZ)V", (void*) android_view_GLES20Canvas_prepare },
+ { "nPrepareDirty", "(JIIIIZ)V", (void*) android_view_GLES20Canvas_prepareDirty },
{ "nFinish", "(J)V", (void*) android_view_GLES20Canvas_finish },
{ "nSetProperty", "(Ljava/lang/String;Ljava/lang/String;)V",
(void*) android_view_GLES20Canvas_setProperty },
- { "nCallDrawGLFunction", "(JJ)I", (void*) android_view_GLES20Canvas_callDrawGLFunction },
+ { "nCallDrawGLFunction", "(JJ)V", (void*) android_view_GLES20Canvas_callDrawGLFunction },
{ "nSave", "(JI)I", (void*) android_view_GLES20Canvas_save },
{ "nRestore", "(J)V", (void*) android_view_GLES20Canvas_restore },
@@ -937,8 +927,7 @@
{ "nDrawPath", "(JJJ)V", (void*) android_view_GLES20Canvas_drawPath },
{ "nDrawLines", "(J[FIIJ)V", (void*) android_view_GLES20Canvas_drawLines },
- { "nSetupPaintFilter", "(JII)V", (void*) android_view_GLES20Canvas_setupPaintFilter },
- { "nResetPaintFilter", "(J)V", (void*) android_view_GLES20Canvas_resetPaintFilter },
+ { "nSetDrawFilter", "(JJ)V", (void*) android_view_GLES20Canvas_setDrawFilter },
{ "nDrawText", "(J[CIIFFIJJ)V", (void*) android_view_GLES20Canvas_drawTextArray },
{ "nDrawText", "(JLjava/lang/String;IIFFIJJ)V",
@@ -948,14 +937,14 @@
{ "nDrawTextOnPath", "(JLjava/lang/String;IIJFFIJJ)V",
(void*) android_view_GLES20Canvas_drawTextOnPath },
- { "nDrawTextRun", "(J[CIIIIFFZJJ)V", (void*) android_view_GLES20Canvas_drawTextRunArray },
+ { "nDrawTextRun", "(J[CIIIIFFZJJ)V", (void*) android_view_GLES20Canvas_drawTextRunArray },
{ "nDrawTextRun", "(JLjava/lang/String;IIIIFFZJJ)V",
(void*) android_view_GLES20Canvas_drawTextRun },
{ "nGetClipBounds", "(JLandroid/graphics/Rect;)Z", (void*) android_view_GLES20Canvas_getClipBounds },
- { "nFinishRecording", "(J)J", (void*) android_view_GLES20Canvas_finishRecording },
- { "nDrawRenderNode", "(JJLandroid/graphics/Rect;I)I", (void*) android_view_GLES20Canvas_drawRenderNode },
+ { "nFinishRecording", "(J)J", (void*) android_view_GLES20Canvas_finishRecording },
+ { "nDrawRenderNode", "(JJI)V", (void*) android_view_GLES20Canvas_drawRenderNode },
{ "nCreateDisplayListRenderer", "()J", (void*) android_view_GLES20Canvas_createDisplayListRenderer },
diff --git a/core/jni/com_android_internal_os_Zygote.cpp b/core/jni/com_android_internal_os_Zygote.cpp
index 4f5e08b..69d9387 100644
--- a/core/jni/com_android_internal_os_Zygote.cpp
+++ b/core/jni/com_android_internal_os_Zygote.cpp
@@ -43,7 +43,6 @@
#include <utils/String8.h>
#include <selinux/android.h>
#include <processgroup/processgroup.h>
-#include <inttypes.h>
#include "android_runtime/AndroidRuntime.h"
#include "JNIHelp.h"
@@ -131,7 +130,7 @@
int err = sigaction(SIGCHLD, &sa, NULL);
if (err < 0) {
- ALOGW("Error setting SIGCHLD handler: %d", errno);
+ ALOGW("Error setting SIGCHLD handler: %s", strerror(errno));
}
}
@@ -143,7 +142,7 @@
int err = sigaction(SIGCHLD, &sa, NULL);
if (err < 0) {
- ALOGW("Error unsetting SIGCHLD handler: %d", errno);
+ ALOGW("Error unsetting SIGCHLD handler: %s", strerror(errno));
}
}
@@ -258,7 +257,7 @@
// Create a second private mount namespace for our process
if (unshare(CLONE_NEWNS) == -1) {
- ALOGW("Failed to unshare(): %d", errno);
+ ALOGW("Failed to unshare(): %s", strerror(errno));
return false;
}
@@ -295,14 +294,15 @@
if (mount_mode == MOUNT_EXTERNAL_MULTIUSER_ALL) {
// Mount entire external storage tree for all users
if (TEMP_FAILURE_RETRY(mount(source, target, NULL, MS_BIND, NULL)) == -1) {
- ALOGW("Failed to mount %s to %s :%d", source, target, errno);
+ ALOGW("Failed to mount %s to %s: %s", source, target, strerror(errno));
return false;
}
} else {
// Only mount user-specific external storage
- if (TEMP_FAILURE_RETRY(
- mount(source_user.string(), target_user.string(), NULL, MS_BIND, NULL)) == -1) {
- ALOGW("Failed to mount %s to %s: %d", source_user.string(), target_user.string(), errno);
+ if (TEMP_FAILURE_RETRY(mount(source_user.string(), target_user.string(), NULL,
+ MS_BIND, NULL)) == -1) {
+ ALOGW("Failed to mount %s to %s: %s", source_user.string(), target_user.string(),
+ strerror(errno));
return false;
}
}
@@ -314,7 +314,7 @@
// Finally, mount user-specific path into place for legacy users
if (TEMP_FAILURE_RETRY(
mount(target_user.string(), legacy, NULL, MS_BIND | MS_REC, NULL)) == -1) {
- ALOGW("Failed to mount %s to %s: %d", target_user.string(), legacy, errno);
+ ALOGW("Failed to mount %s to %s: %s", target_user.string(), legacy, strerror(errno));
return false;
}
} else {
@@ -365,13 +365,13 @@
for (i = 0; i < count; i++) {
devnull = open("/dev/null", O_RDWR);
if (devnull < 0) {
- ALOGE("Failed to open /dev/null");
+ ALOGE("Failed to open /dev/null: %s", strerror(errno));
RuntimeAbort(env);
continue;
}
- ALOGV("Switching descriptor %d to /dev/null: %d", ar[i], errno);
+ ALOGV("Switching descriptor %d to /dev/null: %s", ar[i], strerror(errno));
if (dup2(devnull, ar[i]) < 0) {
- ALOGE("Failed dup2() on descriptor %d", ar[i]);
+ ALOGE("Failed dup2() on descriptor %d: %s", ar[i], strerror(errno));
RuntimeAbort(env);
}
close(devnull);
@@ -401,23 +401,7 @@
strlcpy(buf, s, sizeof(buf)-1);
errno = pthread_setname_np(pthread_self(), buf);
if (errno != 0) {
- ALOGW("Unable to set the name of current thread to '%s'", buf);
- }
-}
-
- // Temporary timing check.
-uint64_t MsTime() {
- timespec now;
- clock_gettime(CLOCK_MONOTONIC, &now);
- return static_cast<uint64_t>(now.tv_sec) * UINT64_C(1000) + now.tv_nsec / UINT64_C(1000000);
-}
-
-
-void ckTime(uint64_t start, const char* where) {
- uint64_t now = MsTime();
- if ((now-start) > 1000) {
- // If we are taking more than a second, log about it.
- ALOGW("Slow operation: %"PRIu64" ms in %s", (uint64_t)(now-start), where);
+ ALOGW("Unable to set the name of current thread to '%s': %s", buf, strerror(errno));
}
}
@@ -429,9 +413,7 @@
jstring java_se_info, jstring java_se_name,
bool is_system_server, jintArray fdsToClose,
jstring instructionSet, jstring dataDir) {
- uint64_t start = MsTime();
SetSigChldHandler();
- ckTime(start, "ForkAndSpecializeCommon:SetSigChldHandler");
pid_t pid = fork();
@@ -439,12 +421,9 @@
// The child process.
gMallocLeakZygoteChild = 1;
-
// Clean up any descriptors which must be closed immediately
DetachDescriptors(env, fdsToClose);
- ckTime(start, "ForkAndSpecializeCommon:Fork and detach");
-
// Keep capabilities across UID change, unless we're staying root.
if (uid != 0) {
EnableKeepCapabilities(env);
@@ -504,13 +483,13 @@
int rc = setresgid(gid, gid, gid);
if (rc == -1) {
- ALOGE("setresgid(%d) failed", gid);
+ ALOGE("setresgid(%d) failed: %s", gid, strerror(errno));
RuntimeAbort(env);
}
rc = setresuid(uid, uid, uid);
if (rc == -1) {
- ALOGE("setresuid(%d) failed", uid);
+ ALOGE("setresuid(%d) failed: %s", uid, strerror(errno));
RuntimeAbort(env);
}
@@ -519,7 +498,7 @@
int old_personality = personality(0xffffffff);
int new_personality = personality(old_personality | ADDR_NO_RANDOMIZE);
if (new_personality == -1) {
- ALOGW("personality(%d) failed", new_personality);
+ ALOGW("personality(%d) failed: %s", new_personality, strerror(errno));
}
}
@@ -568,11 +547,8 @@
UnsetSigChldHandler();
- ckTime(start, "ForkAndSpecializeCommon:child process setup");
-
env->CallStaticVoidMethod(gZygoteClass, gCallPostForkChildHooks, debug_flags,
is_system_server ? NULL : instructionSet);
- ckTime(start, "ForkAndSpecializeCommon:PostForkChildHooks returns");
if (env->ExceptionCheck()) {
ALOGE("Error calling post fork hooks.");
RuntimeAbort(env);
diff --git a/core/jni/com_android_internal_os_ZygoteInit.cpp b/core/jni/com_android_internal_os_ZygoteInit.cpp
index 2233ee3..10c6e2ce 100644
--- a/core/jni/com_android_internal_os_ZygoteInit.cpp
+++ b/core/jni/com_android_internal_os_ZygoteInit.cpp
@@ -96,7 +96,7 @@
fd = jniGetFDFromFileDescriptor(env, in);
- if (env->ExceptionOccurred() != NULL) {
+ if (env->ExceptionCheck()) {
return;
}
@@ -106,7 +106,7 @@
fd = jniGetFDFromFileDescriptor(env, out);
- if (env->ExceptionOccurred() != NULL) {
+ if (env->ExceptionCheck()) {
return;
}
@@ -116,7 +116,7 @@
fd = jniGetFDFromFileDescriptor(env, errfd);
- if (env->ExceptionOccurred() != NULL) {
+ if (env->ExceptionCheck()) {
return;
}
@@ -134,7 +134,7 @@
fd = jniGetFDFromFileDescriptor(env, descriptor);
- if (env->ExceptionOccurred() != NULL) {
+ if (env->ExceptionCheck()) {
return;
}
@@ -170,7 +170,7 @@
jsize length = env->GetArrayLength(fds);
fd_set fdset;
- if (env->ExceptionOccurred() != NULL) {
+ if (env->ExceptionCheck()) {
return -1;
}
@@ -179,14 +179,14 @@
int nfds = 0;
for (jsize i = 0; i < length; i++) {
jobject fdObj = env->GetObjectArrayElement(fds, i);
- if (env->ExceptionOccurred() != NULL) {
+ if (env->ExceptionCheck()) {
return -1;
}
if (fdObj == NULL) {
continue;
}
int fd = jniGetFDFromFileDescriptor(env, fdObj);
- if (env->ExceptionOccurred() != NULL) {
+ if (env->ExceptionCheck()) {
return -1;
}
@@ -209,14 +209,14 @@
for (jsize i = 0; i < length; i++) {
jobject fdObj = env->GetObjectArrayElement(fds, i);
- if (env->ExceptionOccurred() != NULL) {
+ if (env->ExceptionCheck()) {
return -1;
}
if (fdObj == NULL) {
continue;
}
int fd = jniGetFDFromFileDescriptor(env, fdObj);
- if (env->ExceptionOccurred() != NULL) {
+ if (env->ExceptionCheck()) {
return -1;
}
if (FD_ISSET(fd, &fdset)) {
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 216a901..c814979 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -236,6 +236,7 @@
<protected-broadcast android:name="com.android.server.WifiManager.action.DELAYED_DRIVER_STOP" />
<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" />
<protected-broadcast android:name="android.net.wifi.WIFI_SCAN_AVAILABLE" />
<protected-broadcast android:name="android.net.wifi.SCAN_RESULTS" />
<protected-broadcast android:name="android.net.wifi.RSSI_CHANGED" />
@@ -827,6 +828,21 @@
android:permissionGroup="android.permission-group.NETWORK"
android:protectionLevel="signature|system" />
+ <!-- @SystemApi @hide Allow system apps to receive broadcast
+ when a wifi network credential is changed.
+ <p>Not for use by third-party applications. -->
+ <permission android:name="android.permission.RECEIVE_WIFI_CREDENTIAL_CHANGE"
+ android:permissionGroup="android.permission-group.NETWORK"
+ android:protectionLevel="signature|system" />
+
+ <!-- @SystemApi @hide Allows an application to modify any wifi configuration, even if created
+ by another application. Once reconfigured the original creator canot make any further
+ modifications.
+ <p>Not for use by third-party applications. -->
+ <permission android:name="android.permission.OVERRIDE_WIFI_CONFIG"
+ android:permissionGroup="android.permission-group.NETWORK"
+ android:protectionLevel="signature|system" />
+
<!-- @hide -->
<permission android:name="android.permission.ACCESS_WIMAX_STATE"
android:permissionGroup="android.permission-group.NETWORK"
@@ -2273,6 +2289,14 @@
android:description="@string/permdesc_modifyParentalControls"
android:protectionLevel="signature|system" />
+ <!-- Must be required by a {@link android.media.routing.MediaRouteService}
+ to ensure that only the system can interact with it.
+ @hide -->
+ <permission android:name="android.permission.BIND_ROUTE_PROVIDER"
+ android:label="@string/permlab_bindRouteProvider"
+ android:description="@string/permdesc_bindRouteProvider"
+ android:protectionLevel="signature" />
+
<!-- Must be required by device administration receiver, to ensure that only the
system can interact with it. -->
<permission android:name="android.permission.BIND_DEVICE_ADMIN"
@@ -2846,6 +2870,13 @@
android:description="@string/permdesc_bindConditionProviderService"
android:protectionLevel="signature" />
+ <!-- Must be required by a {@link android.media.routing.MediaRouteService},
+ to ensure that only the system can bind to it. -->
+ <permission android:name="android.permission.BIND_MEDIA_ROUTE_SERVICE"
+ android:label="@string/permlab_bindMediaRouteService"
+ android:description="@string/permdesc_bindMediaRouteService"
+ android:protectionLevel="signature" />
+
<!-- Must be required by an {@link android.service.dreams.DreamService},
to ensure that only the system can bind to it. -->
<permission android:name="android.permission.BIND_DREAM_SERVICE"
@@ -2940,7 +2971,7 @@
android:label="@string/managed_profile_label">
</activity-alias>
<activity android:name="com.android.internal.app.HeavyWeightSwitcherActivity"
- android:theme="@style/Theme.Material.Dialog"
+ android:theme="@style/Theme.Material.Light.Dialog"
android:label="@string/heavy_weight_switcher_title"
android:finishOnCloseSystemDialogs="true"
android:excludeFromRecents="true"
@@ -2960,7 +2991,7 @@
<activity android:name="android.accounts.ChooseAccountActivity"
android:excludeFromRecents="true"
android:exported="true"
- android:theme="@android:style/Theme.Material.Dialog"
+ android:theme="@style/Theme.Material.Light.Dialog"
android:label="@string/choose_account_label"
android:process=":ui">
</activity>
@@ -2968,14 +2999,14 @@
<activity android:name="android.accounts.ChooseTypeAndAccountActivity"
android:excludeFromRecents="true"
android:exported="true"
- android:theme="@android:style/Theme.Material.Dialog"
+ android:theme="@style/Theme.Material.Light.Dialog"
android:label="@string/choose_account_label"
android:process=":ui">
</activity>
<activity android:name="android.accounts.ChooseAccountTypeActivity"
android:excludeFromRecents="true"
- android:theme="@android:style/Theme.Material.Dialog"
+ android:theme="@style/Theme.Material.Light.Dialog"
android:label="@string/choose_account_label"
android:process=":ui">
</activity>
@@ -2983,19 +3014,19 @@
<activity android:name="android.accounts.CantAddAccountActivity"
android:excludeFromRecents="true"
android:exported="true"
- android:theme="@android:style/Theme.Material.Dialog.NoActionBar"
+ android:theme="@style/Theme.Material.Light.Dialog.NoActionBar"
android:process=":ui">
</activity>
<activity android:name="android.accounts.GrantCredentialsPermissionActivity"
android:excludeFromRecents="true"
android:exported="true"
- android:theme="@android:style/Theme.Material.DialogWhenLarge"
+ android:theme="@style/Theme.Material.Light.DialogWhenLarge"
android:process=":ui">
</activity>
<activity android:name="android.content.SyncActivityTooManyDeletes"
- android:theme="@android:style/Theme.Holo.Dialog"
+ android:theme="@style/Theme.Material.Light.Dialog"
android:label="@string/sync_too_many_deletes"
android:process=":ui">
</activity>
@@ -3014,7 +3045,7 @@
</activity>
<activity android:name="com.android.internal.app.NetInitiatedActivity"
- android:theme="@style/Theme.Holo.Dialog.Alert"
+ android:theme="@style/Theme.Material.Light.Dialog.Alert"
android:excludeFromRecents="true"
android:process=":ui">
</activity>
diff --git a/core/res/res/layout/activity_chooser_view_list_item.xml b/core/res/res/layout/activity_chooser_view_list_item.xml
index af70234..66e400a 100644
--- a/core/res/res/layout/activity_chooser_view_list_item.xml
+++ b/core/res/res/layout/activity_chooser_view_list_item.xml
@@ -17,11 +17,11 @@
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/list_item"
android:layout_width="match_parent"
- android:layout_height="?android:attr/dropdownListPreferredItemHeight"
- android:paddingStart="16dip"
- android:paddingEnd="16dip"
+ android:layout_height="?attr/dropdownListPreferredItemHeight"
+ android:paddingStart="?attr/listPreferredItemPaddingStart"
+ android:paddingEnd="?attr/listPreferredItemPaddingEnd"
android:minWidth="196dip"
- android:background="?android:attr/activatedBackgroundIndicator"
+ android:background="?attr/activatedBackgroundIndicator"
android:orientation="vertical" >
<LinearLayout
@@ -42,7 +42,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
- android:textAppearance="?android:attr/textAppearanceLargePopupMenu"
+ android:textAppearance="?attr/textAppearanceLargePopupMenu"
android:duplicateParentState="true"
android:singleLine="true"
android:ellipsize="marquee"
diff --git a/core/res/res/layout/activity_list_item_2.xml b/core/res/res/layout/activity_list_item_2.xml
index a5a4cf9..608e986 100644
--- a/core/res/res/layout/activity_list_item_2.xml
+++ b/core/res/res/layout/activity_list_item_2.xml
@@ -17,9 +17,9 @@
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:minHeight="?android:attr/listPreferredItemHeight"
- android:textAppearance="?android:attr/textAppearanceListItemSmall"
+ android:minHeight="?attr/listPreferredItemHeight"
+ android:textAppearance="?attr/textAppearanceListItemSmall"
android:gravity="center_vertical"
android:drawablePadding="14dip"
- android:paddingStart="16dip"
- android:paddingEnd="16dip" />
+ android:paddingStart="?attr/listPreferredItemPaddingStart"
+ android:paddingEnd="?attr/listPreferredItemPaddingEnd" />
diff --git a/core/res/res/layout/alert_dialog_material.xml b/core/res/res/layout/alert_dialog_material.xml
index 5627a2c..29bfaa7 100644
--- a/core/res/res/layout/alert_dialog_material.xml
+++ b/core/res/res/layout/alert_dialog_material.xml
@@ -31,9 +31,9 @@
android:layout_height="wrap_content"
android:orientation="horizontal"
android:gravity="center_vertical|start"
- android:paddingStart="@dimen/alert_dialog_padding_material"
- android:paddingEnd="@dimen/alert_dialog_padding_material"
- android:paddingTop="@dimen/alert_dialog_padding_top_material">
+ android:paddingStart="?attr/dialogPreferredPadding"
+ android:paddingEnd="?attr/dialogPreferredPadding"
+ android:paddingTop="@dimen/dialog_padding_top_material">
<ImageView android:id="@+id/icon"
android:layout_width="32dip"
android:layout_height="32dip"
@@ -74,13 +74,13 @@
style="@style/TextAppearance.Material.Subhead"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:paddingStart="@dimen/alert_dialog_padding_material"
- android:paddingTop="@dimen/alert_dialog_padding_top_material"
- android:paddingEnd="@dimen/alert_dialog_padding_material" />
+ android:paddingStart="?attr/dialogPreferredPadding"
+ android:paddingTop="@dimen/dialog_padding_top_material"
+ android:paddingEnd="?attr/dialogPreferredPadding" />
<Space android:id="@+id/textSpacerNoButtons"
android:visibility="gone"
android:layout_width="0dp"
- android:layout_height="@dimen/alert_dialog_padding_top_material" />
+ android:layout_height="@dimen/dialog_padding_top_material" />
</LinearLayout>
</ScrollView>
<View android:id="@+id/scrollIndicatorDown"
diff --git a/core/res/res/layout/alert_dialog_progress_material.xml b/core/res/res/layout/alert_dialog_progress_material.xml
index d005a44..9c21540 100644
--- a/core/res/res/layout/alert_dialog_progress_material.xml
+++ b/core/res/res/layout/alert_dialog_progress_material.xml
@@ -18,10 +18,10 @@
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="match_parent"
- android:paddingStart="@dimen/alert_dialog_padding_material"
- android:paddingTop="@dimen/alert_dialog_padding_top_material"
- android:paddingEnd="@dimen/alert_dialog_padding_material"
- android:paddingBottom="@dimen/alert_dialog_padding_top_material">
+ android:paddingStart="?attr/dialogPreferredPadding"
+ android:paddingTop="@dimen/dialog_padding_top_material"
+ android:paddingEnd="?attr/dialogPreferredPadding"
+ android:paddingBottom="@dimen/dialog_padding_top_material">
<ProgressBar
android:id="@+id/progress"
style="?attr/progressBarStyleHorizontal"
diff --git a/core/res/res/layout/app_not_authorized.xml b/core/res/res/layout/app_not_authorized.xml
index 2188511..339b24e 100644
--- a/core/res/res/layout/app_not_authorized.xml
+++ b/core/res/res/layout/app_not_authorized.xml
@@ -26,30 +26,33 @@
<TextView android:id="@+id/description"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:textAppearance="?android:attr/textAppearanceMedium"
android:layout_gravity="start|center_vertical"
- android:paddingTop="16dip"
- android:paddingBottom="16dip"
- android:paddingStart="16dip"
- android:paddingEnd="16dip"
+ android:paddingStart="?attr/dialogPreferredPadding"
+ android:paddingTop="@dimen/dialog_padding_top_material"
+ android:paddingEnd="?attr/dialogPreferredPadding"
android:text="@string/error_message_change_not_allowed"
- />
+ style="@style/TextAppearance.Material.Subhead" />
- <!-- Horizontal divider line -->
- <View android:layout_height="1dip"
- android:layout_width="match_parent"
- android:background="?android:attr/dividerHorizontal" />
-
- <!-- Alert dialog style buttons along the bottom. -->
- <LinearLayout android:id="@+id/button_bar"
- style="?android:attr/buttonBarStyle"
+ <LinearLayout android:id="@+id/buttonPanel"
+ style="?attr/buttonBarStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:measureWithLargestChild="true">
- <Button android:id="@android:id/button1"
- style="?android:attr/buttonBarButtonStyle"
- android:layout_width="wrap_content" android:layout_height="wrap_content"
+ android:layoutDirection="locale"
+ android:orientation="horizontal"
+ android:paddingStart="12dp"
+ android:paddingEnd="12dp"
+ android:paddingTop="8dp"
+ android:paddingBottom="8dp"
+ android:gravity="bottom">
+ <Space
+ android:layout_width="0dp"
+ android:layout_height="0dp"
android:layout_weight="1"
+ android:visibility="invisible" />
+ <Button android:id="@+id/button1"
+ style="?attr/buttonBarNegativeButtonStyle"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
android:text="@android:string/yes"
android:onClick="onCancelButtonClicked" />
</LinearLayout>
diff --git a/core/res/res/layout/choose_account.xml b/core/res/res/layout/choose_account.xml
index 45a944e..e13dd26 100644
--- a/core/res/res/layout/choose_account.xml
+++ b/core/res/res/layout/choose_account.xml
@@ -21,11 +21,11 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
- android:paddingStart="16dip"
- android:paddingEnd="16dip">
+ android:paddingStart="?attr/dialogPreferredPadding"
+ android:paddingEnd="?attr/dialogPreferredPadding">
<ListView xmlns:android="http://schemas.android.com/apk/res/android"
- android:id="@android:id/list"
+ android:id="@id/list"
android:layout_width="match_parent"
android:layout_height="0dip"
android:layout_weight="1"
diff --git a/core/res/res/layout/choose_account_row.xml b/core/res/res/layout/choose_account_row.xml
index c4247b6..71537fb 100644
--- a/core/res/res/layout/choose_account_row.xml
+++ b/core/res/res/layout/choose_account_row.xml
@@ -18,8 +18,8 @@
-->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:paddingStart="16dip"
- android:paddingEnd="16dip"
+ android:paddingStart="?attr/listPreferredItemPaddingStart"
+ android:paddingEnd="?attr/listPreferredItemPaddingEnd"
android:orientation="horizontal" >
<ImageView android:id="@+id/account_row_icon"
@@ -31,8 +31,8 @@
android:id="@+id/account_row_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:textAppearance="?android:attr/textAppearanceMedium"
+ android:textAppearance="?android:attr/textAppearanceListItem"
android:gravity="center_vertical"
- android:minHeight="?android:attr/listPreferredItemHeight" />
+ android:minHeight="?attr/listPreferredItemHeight" />
-</LinearLayout>
\ No newline at end of file
+</LinearLayout>
diff --git a/core/res/res/layout/choose_type_and_account.xml b/core/res/res/layout/choose_type_and_account.xml
index bf06054..79f3f1a 100644
--- a/core/res/res/layout/choose_type_and_account.xml
+++ b/core/res/res/layout/choose_type_and_account.xml
@@ -26,45 +26,52 @@
<TextView android:id="@+id/description"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:textAppearance="?android:attr/textAppearanceMedium"
android:layout_gravity="start|center_vertical"
- android:paddingTop="16dip"
- android:paddingBottom="16dip"
- android:paddingStart="16dip"
- android:paddingEnd="16dip"
- />
+ android:paddingStart="?attr/dialogPreferredPadding"
+ android:paddingTop="@dimen/dialog_padding_top_material"
+ android:paddingEnd="?attr/dialogPreferredPadding"
+ style="@style/TextAppearance.Material.Subhead" />
- <!-- List of accounts, with "Add new account" as the last item -->
- <ListView android:id="@android:id/list"
+ <FrameLayout android:id="@+id/contentPanel"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:drawSelectorOnTop="false"
android:layout_weight="1"
- android:scrollbarAlwaysDrawVerticalTrack="true"
- android:choiceMode="singleChoice" />
+ android:minHeight="48dp">
+ <ListView android:id="@id/list"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:drawSelectorOnTop="false"
+ android:layout_weight="1"
+ android:scrollbarAlwaysDrawVerticalTrack="true"
+ android:choiceMode="singleChoice" />
+ </FrameLayout>
- <!-- Horizontal divider line -->
- <View android:layout_height="1dip"
- android:layout_width="match_parent"
- android:background="?android:attr/dividerHorizontal" />
-
- <!-- Alert dialog style buttons along the bottom. -->
- <LinearLayout android:id="@+id/button_bar"
- style="?android:attr/buttonBarStyle"
+ <LinearLayout android:id="@+id/buttonPanel"
+ style="?attr/buttonBarStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:measureWithLargestChild="true">
- <Button android:id="@android:id/button1"
- style="?android:attr/buttonBarButtonStyle"
- android:layout_width="wrap_content" android:layout_height="wrap_content"
+ android:layoutDirection="locale"
+ android:orientation="horizontal"
+ android:paddingStart="12dp"
+ android:paddingEnd="12dp"
+ android:paddingTop="8dp"
+ android:paddingBottom="8dp"
+ android:gravity="bottom">
+ <Space
+ android:layout_width="0dp"
+ android:layout_height="0dp"
android:layout_weight="1"
- android:text="@android:string/no"
- android:onClick="onCancelButtonClicked" />
- <Button android:id="@android:id/button2"
- style="?android:attr/buttonBarButtonStyle"
+ android:visibility="invisible" />
+ <Button android:id="@+id/button1"
+ style="?attr/buttonBarNegativeButtonStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:layout_weight="1"
+ android:text="@android:string/no"
+ android:onClick="onCancelButtonClicked" />
+ <Button android:id="@+id/button2"
+ style="?attr/buttonBarPositiveButtonStyle"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
android:text="@android:string/yes"
android:onClick="onOkButtonClicked" />
</LinearLayout>
diff --git a/core/res/res/layout/dialog_title_icons_material.xml b/core/res/res/layout/dialog_title_icons_material.xml
index 21396da..62af096 100644
--- a/core/res/res/layout/dialog_title_icons_material.xml
+++ b/core/res/res/layout/dialog_title_icons_material.xml
@@ -28,9 +28,9 @@
android:layout_height="wrap_content"
android:orientation="horizontal"
android:gravity="center_vertical"
- android:paddingStart="@dimen/alert_dialog_padding_material"
- android:paddingEnd="@dimen/alert_dialog_padding_material"
- android:paddingTop="@dimen/alert_dialog_padding_material">
+ android:paddingStart="?attr/dialogPreferredPadding"
+ android:paddingEnd="?attr/dialogPreferredPadding"
+ android:paddingTop="?attr/dialogPreferredPadding">
<ImageView android:id="@+id/left_icon"
android:layout_width="32dip"
android:layout_height="32dip"
diff --git a/core/res/res/layout/dialog_title_material.xml b/core/res/res/layout/dialog_title_material.xml
index fcf6164..339d569 100644
--- a/core/res/res/layout/dialog_title_material.xml
+++ b/core/res/res/layout/dialog_title_material.xml
@@ -29,9 +29,9 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textAlignment="viewStart"
- android:paddingStart="@dimen/alert_dialog_padding_material"
- android:paddingEnd="@dimen/alert_dialog_padding_material"
- android:paddingTop="@dimen/alert_dialog_padding_top_material" />
+ android:paddingStart="?attr/dialogPreferredPadding"
+ android:paddingEnd="?attr/dialogPreferredPadding"
+ android:paddingTop="@dimen/dialog_padding_top_material" />
<FrameLayout
android:layout_width="match_parent" android:layout_height="wrap_content"
android:layout_weight="1"
diff --git a/core/res/res/layout/locale_picker_item.xml b/core/res/res/layout/locale_picker_item.xml
index 94c9baf..defdd4d 100644
--- a/core/res/res/layout/locale_picker_item.xml
+++ b/core/res/res/layout/locale_picker_item.xml
@@ -19,15 +19,14 @@
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:gravity="center_vertical"
- android:minHeight="?android:attr/listPreferredItemHeight"
- android:paddingStart="16dp"
+ android:minHeight="?attr/listPreferredItemHeight"
+ android:paddingStart="?attr/listPreferredItemPaddingStart"
+ android:paddingEnd="?attr/listPreferredItemPaddingEnd"
android:paddingTop="8dp"
- android:paddingBottom="8dp"
- android:paddingEnd="16dp">
+ android:paddingBottom="8dp">
<TextView android:id="@+id/locale"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:textAppearance="?android:attr/textAppearanceMedium"
- />
-</LinearLayout >
+ android:textAppearance="?android:attr/textAppearanceListItem" />
+</LinearLayout>
diff --git a/core/res/res/layout/popup_menu_item_layout.xml b/core/res/res/layout/popup_menu_item_layout.xml
index 452f85d..0bc636f 100644
--- a/core/res/res/layout/popup_menu_item_layout.xml
+++ b/core/res/res/layout/popup_menu_item_layout.xml
@@ -16,7 +16,7 @@
<com.android.internal.view.menu.ListMenuItemView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
- android:layout_height="?android:attr/dropdownListPreferredItemHeight"
+ android:layout_height="?attr/dropdownListPreferredItemHeight"
android:minWidth="196dip"
android:paddingEnd="16dip">
@@ -37,7 +37,7 @@
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_alignParentStart="true"
- android:textAppearance="?android:attr/textAppearanceLargePopupMenu"
+ android:textAppearance="?attr/textAppearanceLargePopupMenu"
android:singleLine="true"
android:duplicateParentState="true"
android:ellipsize="marquee"
@@ -50,7 +50,7 @@
android:layout_height="wrap_content"
android:layout_below="@id/title"
android:layout_alignParentStart="true"
- android:textAppearance="?android:attr/textAppearanceSmallPopupMenu"
+ android:textAppearance="?attr/textAppearanceSmallPopupMenu"
android:singleLine="true"
android:duplicateParentState="true"
android:textAlignment="viewStart" />
diff --git a/core/res/res/layout/progress_dialog_material.xml b/core/res/res/layout/progress_dialog_material.xml
index 54af106..2417965 100644
--- a/core/res/res/layout/progress_dialog_material.xml
+++ b/core/res/res/layout/progress_dialog_material.xml
@@ -25,10 +25,10 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:baselineAligned="false"
- android:paddingStart="@dimen/alert_dialog_padding_material"
- android:paddingTop="@dimen/alert_dialog_padding_top_material"
- android:paddingEnd="@dimen/alert_dialog_padding_material"
- android:paddingBottom="@dimen/alert_dialog_padding_top_material">
+ android:paddingStart="?attr/dialogPreferredPadding"
+ android:paddingTop="@dimen/dialog_padding_top_material"
+ android:paddingEnd="?attr/dialogPreferredPadding"
+ android:paddingBottom="@dimen/dialog_padding_top_material">
<ProgressBar
android:id="@id/progress"
@@ -36,7 +36,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:max="10000"
- android:layout_marginEnd="@dimen/alert_dialog_padding_material" />
+ android:layout_marginEnd="?attr/dialogPreferredPadding" />
<TextView
android:id="@+id/message"
diff --git a/core/res/res/layout/resolve_list_item.xml b/core/res/res/layout/resolve_list_item.xml
index 37c4270..2933a6a 100644
--- a/core/res/res/layout/resolve_list_item.xml
+++ b/core/res/res/layout/resolve_list_item.xml
@@ -32,8 +32,8 @@
android:layout_width="24dp"
android:layout_height="24dp"
android:layout_gravity="start|center_vertical"
- android:layout_marginStart="16dp"
- android:layout_marginEnd="16dp"
+ android:layout_marginStart="?attr/listPreferredItemPaddingStart"
+ android:layout_marginEnd="?attr/listPreferredItemPaddingEnd"
android:layout_marginTop="12dp"
android:layout_marginBottom="12dp"
android:scaleType="fitCenter" />
@@ -41,8 +41,8 @@
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:gravity="start|center_vertical"
android:orientation="vertical"
- android:paddingStart="16dp"
- android:paddingEnd="16dp"
+ android:paddingStart="?attr/listPreferredItemPaddingStart"
+ android:paddingEnd="?attr/listPreferredItemPaddingEnd"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:layout_gravity="start|center_vertical">
diff --git a/core/res/res/layout/resolver_list.xml b/core/res/res/layout/resolver_list.xml
index 727f9c6..9ae3aec 100644
--- a/core/res/res/layout/resolver_list.xml
+++ b/core/res/res/layout/resolver_list.xml
@@ -23,23 +23,21 @@
android:maxWidth="@dimen/resolver_max_width"
android:maxCollapsedHeight="192dp"
android:maxCollapsedHeightSmall="56dp"
- android:id="@id/contentPanel"
- >
+ android:id="@id/contentPanel">
<TextView android:id="@+id/title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alwaysShow="true"
android:minHeight="56dp"
- android:textAppearance="?android:attr/textAppearanceMedium"
+ android:textAppearance="?attr/textAppearanceMedium"
android:gravity="start|center_vertical"
- android:paddingStart="16dp"
- android:paddingEnd="16dp"
+ android:paddingStart="?attr/dialogPreferredPadding"
+ android:paddingEnd="?attr/dialogPreferredPadding"
android:paddingTop="8dp"
android:paddingBottom="8dp"
android:background="@color/white"
- android:elevation="8dp"
- />
+ android:elevation="8dp" />
<ListView
android:layout_width="match_parent"
@@ -50,8 +48,7 @@
android:background="@color/white"
android:elevation="8dp"
android:nestedScrollingEnabled="true"
- android:divider="@null"
- />
+ android:divider="@null" />
<TextView android:id="@+id/empty"
android:layout_width="match_parent"
diff --git a/core/res/res/layout/select_dialog_multichoice_material.xml b/core/res/res/layout/select_dialog_multichoice_material.xml
index e5b5b62..9cfbbb3 100644
--- a/core/res/res/layout/select_dialog_multichoice_material.xml
+++ b/core/res/res/layout/select_dialog_multichoice_material.xml
@@ -23,8 +23,8 @@
android:textAppearance="?android:attr/textAppearanceMedium"
android:textColor="?android:attr/textColorAlertDialogListItem"
android:gravity="center_vertical"
- android:paddingStart="@dimen/alert_dialog_padding_material"
- android:paddingEnd="@dimen/alert_dialog_padding_material"
+ android:paddingStart="?attr/dialogPreferredPadding"
+ android:paddingEnd="?attr/dialogPreferredPadding"
android:checkMark="?android:attr/listChoiceIndicatorMultiple"
android:checkMarkGravity="start"
android:ellipsize="marquee" />
diff --git a/core/res/res/layout/select_dialog_singlechoice_material.xml b/core/res/res/layout/select_dialog_singlechoice_material.xml
index a9e603d..4f8672f 100644
--- a/core/res/res/layout/select_dialog_singlechoice_material.xml
+++ b/core/res/res/layout/select_dialog_singlechoice_material.xml
@@ -23,8 +23,8 @@
android:textAppearance="?android:attr/textAppearanceMedium"
android:textColor="?android:attr/textColorAlertDialogListItem"
android:gravity="center_vertical"
- android:paddingStart="@dimen/alert_dialog_padding_material"
- android:paddingEnd="@dimen/alert_dialog_padding_material"
+ android:paddingStart="?attr/dialogPreferredPadding"
+ android:paddingEnd="?attr/dialogPreferredPadding"
android:checkMark="?android:attr/listChoiceIndicatorSingle"
android:checkMarkGravity="start"
android:ellipsize="marquee" />
diff --git a/core/res/res/layout/simple_account_item.xml b/core/res/res/layout/simple_account_item.xml
index e7b746c..29e42af 100644
--- a/core/res/res/layout/simple_account_item.xml
+++ b/core/res/res/layout/simple_account_item.xml
@@ -18,13 +18,13 @@
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:minHeight="?android:attr/listPreferredItemHeight"
+ android:minHeight="?attr/listPreferredItemHeight"
android:gravity="center_vertical"
- android:paddingStart="16dip"
- android:paddingEnd="?android:attr/scrollbarSize">
+ android:paddingStart="?attr/listPreferredItemPaddingStart"
+ android:paddingEnd="?attr/scrollbarSize">
<ImageView
- android:id="@+android:id/icon"
+ android:id="@id/icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"/>
@@ -36,20 +36,20 @@
android:layout_marginTop="6dip"
android:layout_marginBottom="6dip"
android:layout_weight="1">
- <TextView android:id="@+android:id/title"
+ <TextView android:id="@id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:singleLine="true"
android:ellipsize="none"
- android:textAppearance="?android:attr/textAppearanceListItem" />
- <TextView android:id="@+android:id/summary"
+ android:textAppearance="?attr/textAppearanceListItem" />
+ <TextView android:id="@id/summary"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:layout_below="@android:id/title"
- android:layout_alignStart="@android:id/title"
+ android:layout_below="@id/title"
+ android:layout_alignStart="@id/title"
android:singleLine="true"
android:ellipsize="none"
- android:textAppearance="?android:attr/textAppearanceListItemSecondary"
- android:textColor="?android:attr/textColorSecondary"/>
+ android:textAppearance="?attr/textAppearanceListItemSecondary"
+ android:textColor="?attr/textColorSecondary"/>
</RelativeLayout>
</LinearLayout>
diff --git a/core/res/res/layout/simple_list_item_2_single_choice.xml b/core/res/res/layout/simple_list_item_2_single_choice.xml
index 940c6b8..6cdb88b 100644
--- a/core/res/res/layout/simple_list_item_2_single_choice.xml
+++ b/core/res/res/layout/simple_list_item_2_single_choice.xml
@@ -19,7 +19,7 @@
android:layout_height="wrap_content"
android:orientation="horizontal"
android:gravity="center_vertical"
- android:paddingStart="16dip"
+ android:paddingStart="?attr/listPreferredItemPaddingStart"
android:paddingEnd="12dip"
android:minHeight="?attr/listPreferredItemHeightSmall"
android:background="@color/transparent">
diff --git a/core/res/res/layout/user_switching_dialog.xml b/core/res/res/layout/user_switching_dialog.xml
index 8617e5d..496783a 100644
--- a/core/res/res/layout/user_switching_dialog.xml
+++ b/core/res/res/layout/user_switching_dialog.xml
@@ -21,7 +21,7 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
- android:paddingStart="@dimen/alert_dialog_padding_material"
- android:paddingEnd="@dimen/alert_dialog_padding_material"
+ android:paddingStart="?attr/dialogPreferredPadding"
+ android:paddingEnd="?attr/dialogPreferredPadding"
android:paddingTop="24dp"
android:paddingBottom="24dp" />
diff --git a/core/res/res/values-af/strings.xml b/core/res/res/values-af/strings.xml
index 0dd5cc3..b746031 100644
--- a/core/res/res/values-af/strings.xml
+++ b/core/res/res/values-af/strings.xml
@@ -41,8 +41,6 @@
<string name="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g> sekondes"</string>
<string name="durationSecond" msgid="985669622276420331">"<xliff:g id="SECONDS">%1$d</xliff:g> sekonde"</string>
<string name="untitled" msgid="4638956954852782576">"<Titelloos>"</string>
- <string name="ellipsis" msgid="7899829516048813237">"…"</string>
- <string name="ellipsis_two_dots" msgid="1228078994866030736">"‥"</string>
<string name="emptyPhoneNumber" msgid="7694063042079676517">"(Geen foonnommer)"</string>
<string name="unknownName" msgid="2277556546742746522">"(Onbekend)"</string>
<string name="defaultVoiceMailAlphaTag" msgid="2660020990097733077">"Stemboodskap"</string>
@@ -415,6 +413,8 @@
<string name="permdesc_bindRemoteDisplay" msgid="1261242718727295981">"Dit laat die houer toe om aan die top-koppelvlak van \'n afstandskerm te koppel. Behoort nooit vir gewone programme nodig te wees nie."</string>
<string name="permlab_bindRemoteViews" msgid="5697987759897367099">"bind aan \'n legstukdiens"</string>
<string name="permdesc_bindRemoteViews" msgid="4717987810137692572">"Dit laat die houer toe om aan die topvlak-koppelvlak van \'n legstuk-diens te bind. Dit moet nooit vir normale programme nodig wees nie."</string>
+ <string name="permlab_bindRouteProvider" msgid="4869394607915096847">"bind aan \'n roeteverskafferdiens"</string>
+ <string name="permdesc_bindRouteProvider" msgid="4703804520859960329">"Laat die houer toe om aan enige geregistreerde roeteverskaffers te bind. Behoort nooit vir normale programme nodig te wees nie."</string>
<string name="permlab_bindDeviceAdmin" msgid="8704986163711455010">"skakel met \'n toestel-admin"</string>
<string name="permdesc_bindDeviceAdmin" msgid="569715419543907930">"Laat die houer toe om bedoelings na \'n toesteladministrateur te stuur. Dit moet nooit vir normale programme nodig wees nie."</string>
<string name="permlab_bindTvInput" msgid="5601264742478168987">"bind aan \'n TV-invoer"</string>
@@ -742,6 +742,8 @@
<string name="permdesc_bindNotificationListenerService" msgid="985697918576902986">"Laat die houer toe om aan die top-koppelvlak van \'n kennisgewingluisteraardiens te bind. Behoort nooit vir gewone programme nodig te wees nie."</string>
<string name="permlab_bindConditionProviderService" msgid="1180107672332704641">"verbind met \'n toestandverskafferdiens"</string>
<string name="permdesc_bindConditionProviderService" msgid="1680513931165058425">"Laat die houer toe om met die topvlak-koppelvlak van \'n toestandverskafferdiens te verbind. Behoort nooit vir normale programme nodig te wees nie."</string>
+ <string name="permlab_bindMediaRouteService" msgid="6637740382272686835">"bind aan \'n mediaroetediens"</string>
+ <string name="permdesc_bindMediaRouteService" msgid="6436655024972496687">"Laat die houer toe om aan die topvlakkoppelvlak van \'n mediaroetediens te bind. Behoort nooit vir normale programme nodig te wees nie."</string>
<string name="permlab_bindDreamService" msgid="4153646965978563462">"bind aan \'n droomdiens"</string>
<string name="permdesc_bindDreamService" msgid="7325825272223347863">"Laat die houer toe om aan die topvlak-koppelvlak van \'n droomdiens te bind. Behoort nooit vir normale programme nodig te wees nie."</string>
<string name="permlab_invokeCarrierSetup" msgid="3699600833975117478">"roep die opstellingprogram op wat deur die diensverskaffer voorsien is"</string>
@@ -1283,6 +1285,9 @@
<skip />
<string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"Kon nie aan Wi-Fikoppel nie"</string>
<string name="wifi_watchdog_network_disabled_detailed" msgid="5548780776418332675">" het \'n swak internetverbinding."</string>
+ <string name="wifi_connect_alert_title" msgid="8455846016001810172">"Laat verbinding toe?"</string>
+ <string name="wifi_connect_alert_message" msgid="8930084523889618078">"%1$s wil graag koppel aan %2$s"</string>
+ <string name="wifi_connect_default_application" msgid="7143109390475484319">"\'n Program"</string>
<string name="wifi_p2p_dialog_title" msgid="97611782659324517">"Wi-Fi Direct"</string>
<string name="wifi_p2p_turnon_message" msgid="2909250942299627244">"Begin Wi-Fi Direct. Dit sal die Wi-Fi-kliënt/warmkol afskakel."</string>
<string name="wifi_p2p_failed_message" msgid="3763669677935623084">"Kon nie Wi-Fi Direct begin nie."</string>
diff --git a/core/res/res/values-am/strings.xml b/core/res/res/values-am/strings.xml
index 4cc1096..0317563 100644
--- a/core/res/res/values-am/strings.xml
+++ b/core/res/res/values-am/strings.xml
@@ -41,8 +41,6 @@
<string name="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g> ሴ"</string>
<string name="durationSecond" msgid="985669622276420331">"<xliff:g id="SECONDS">%1$d</xliff:g> ሴ"</string>
<string name="untitled" msgid="4638956954852782576">"<ርዕስ አልባ>"</string>
- <string name="ellipsis" msgid="7899829516048813237">"…"</string>
- <string name="ellipsis_two_dots" msgid="1228078994866030736">"‥"</string>
<string name="emptyPhoneNumber" msgid="7694063042079676517">"(ምንም ስልክ ቁጥር የለም)"</string>
<string name="unknownName" msgid="2277556546742746522">"(ያልታወቀ)"</string>
<string name="defaultVoiceMailAlphaTag" msgid="2660020990097733077">"የድምፅ መልዕክት"</string>
@@ -415,6 +413,8 @@
<string name="permdesc_bindRemoteDisplay" msgid="1261242718727295981">"ያዢው ከአንድ የርቀት ማሳያ ከፍተኛ-ደረጃ በይነገጽ ጋር እንዲጠርዝ ይፈቅድለታል። ለመደበኛ መተግበሪያዎች በጭራሽ አያስፈልግም።"</string>
<string name="permlab_bindRemoteViews" msgid="5697987759897367099">"ወደ ፍርግም አገልግሎት አያይዝ"</string>
<string name="permdesc_bindRemoteViews" msgid="4717987810137692572">"ያዡ ግቤት ስልቱን ወደ ከፍተኛ-ደረጃ ፍርግም አገልግሎት ለመጠረዝ ይፈቅዳሉ። ለመደበኛ መተግበሪያዎች በፍፁም አያስፈልግም።"</string>
+ <string name="permlab_bindRouteProvider" msgid="4869394607915096847">"ከመንገድ አቅራቢዎች አገልግሎት ጋር ያስተሳስሩ"</string>
+ <string name="permdesc_bindRouteProvider" msgid="4703804520859960329">"አቃፊው ከማናቸውም የተመዘገቡ የመንገድ አቅራቢዎች ጋር እንዲተሳሰር ይፈቅድለታል። ለመደበኛ መተግበሪያዎች በጭራሽ ሊያስፈልግ አይገባም።"</string>
<string name="permlab_bindDeviceAdmin" msgid="8704986163711455010">"ከመሣሪያ አስተዳደር ጋር ተገናኝ"</string>
<string name="permdesc_bindDeviceAdmin" msgid="569715419543907930">"ያዡ በይነመረብን ለመሣሪያ አስተዳዳሪ ለመላክ ይፈቅዳሉ። ለመደበኛ መተግበሪያዎች በፍፁም አያስፈልግም።"</string>
<string name="permlab_bindTvInput" msgid="5601264742478168987">"ከአንድ የቴሌቪዥን ግብዓት ጋር እሰር"</string>
@@ -742,6 +742,8 @@
<string name="permdesc_bindNotificationListenerService" msgid="985697918576902986">"ያዢው የማሳወቂያ አዳማጭ አገልግሎቱን ከከፍተኛ-ደረጃ በይነገጹ ጋር እንዲያስር ያስችለዋል። ለመደበኛ መተግበሪያዎች በጭራሽ አያስፈልግም።"</string>
<string name="permlab_bindConditionProviderService" msgid="1180107672332704641">"ከአንድ የሁኔታ አቅራቢ አገልግሎት ጋር ይሰሩ"</string>
<string name="permdesc_bindConditionProviderService" msgid="1680513931165058425">"ያዢው የአንድ የሁኔታ አቅራቢ አገልግሎት የከፍተኛ ደረጃ በይነገጽ እንዲያስር ያስችለዋል። ለመደበኛ መተግበሪያዎች በጭራሽ አያስፈልግም።"</string>
+ <string name="permlab_bindMediaRouteService" msgid="6637740382272686835">"ከአንድ ማህደረመረጃ ማዞር አገልግሎት ጋር ያስተሳስራል"</string>
+ <string name="permdesc_bindMediaRouteService" msgid="6436655024972496687">"ያዢው የአንድ ማህደረመረጃ ማዞር አገልግሎት የከፍተኛ ደረጃ በይነገጽ እንዲያስር ያስችለዋል። ለመደበኛ መተግበሪያዎች በጭራሽ አያስፈልግም።"</string>
<string name="permlab_bindDreamService" msgid="4153646965978563462">"ከህልም አገልግሎት ጋር ጠርዝ"</string>
<string name="permdesc_bindDreamService" msgid="7325825272223347863">"ያዢው የህልም አገልግሎቱን ከከፍተኛ-ደረጃ በይነገጽ ጋር እንዲጠርዝ ይፈቅዳል። ለመደበኛ መተግበሪያዎች በጭራሽ አያስፈልግም።"</string>
<string name="permlab_invokeCarrierSetup" msgid="3699600833975117478">"በድምጸ-ተያያዥ ሞደም የቀረበው የውቅር መተግበሪያውን መጥራት"</string>
@@ -1283,6 +1285,9 @@
<skip />
<string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"ወደ Wi-Fi ለማያያዝ አልተቻለም"</string>
<string name="wifi_watchdog_network_disabled_detailed" msgid="5548780776418332675">" ደካማ የበይነመረብ ግንኙነት ኣለው።"</string>
+ <string name="wifi_connect_alert_title" msgid="8455846016001810172">"ግንኙነት ይፈቀድ?"</string>
+ <string name="wifi_connect_alert_message" msgid="8930084523889618078">"%1$s ከ%2$s ጋር መገናኘት ይፈልጋል"</string>
+ <string name="wifi_connect_default_application" msgid="7143109390475484319">"አንድ መተግበሪያ"</string>
<string name="wifi_p2p_dialog_title" msgid="97611782659324517">"Wi-Fi ቀጥታ"</string>
<string name="wifi_p2p_turnon_message" msgid="2909250942299627244">"የWi-Fi በቀጥታ ጀምር።ይህ የWi-Fi ደንበኛ /ድረስ ነጥብ ያጠፋል።"</string>
<string name="wifi_p2p_failed_message" msgid="3763669677935623084">"በቀጥታ Wi-Fi ማስጀመር አልተቻለም።"</string>
diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml
index f241662..4388c08 100644
--- a/core/res/res/values-ar/strings.xml
+++ b/core/res/res/values-ar/strings.xml
@@ -41,8 +41,6 @@
<string name="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g> ثانية"</string>
<string name="durationSecond" msgid="985669622276420331">"<xliff:g id="SECONDS">%1$d</xliff:g> ثانية"</string>
<string name="untitled" msgid="4638956954852782576">"<بلا عنوان>"</string>
- <string name="ellipsis" msgid="7899829516048813237">"…"</string>
- <string name="ellipsis_two_dots" msgid="1228078994866030736">"‥"</string>
<string name="emptyPhoneNumber" msgid="7694063042079676517">"(ليس هناك رقم هاتف)"</string>
<string name="unknownName" msgid="2277556546742746522">"(غير معروف)"</string>
<string name="defaultVoiceMailAlphaTag" msgid="2660020990097733077">"البريد الصوتي"</string>
@@ -415,6 +413,8 @@
<string name="permdesc_bindRemoteDisplay" msgid="1261242718727295981">"للسماح للمالك بالالتزام بواجهة المستوى العلوي للعرض عن بُعد. لن تكون هناك حاجة إليه مطلقًا مع التطبيقات العادية."</string>
<string name="permlab_bindRemoteViews" msgid="5697987759897367099">"الالتزام بخدمة أداة"</string>
<string name="permdesc_bindRemoteViews" msgid="4717987810137692572">"للسماح للمالك بالالتزام بواجهة المستوى العلوي لخدمة الأداة. لن تكون هناك حاجة إليه مطلقًا مع التطبيقات العادية."</string>
+ <string name="permlab_bindRouteProvider" msgid="4869394607915096847">"الربط مع خدمة مزود طريق"</string>
+ <string name="permdesc_bindRouteProvider" msgid="4703804520859960329">"للسماح لحامل البطاقة الربط مع أي مزود طريق مسجل. لا يجب استخدامه على الإطلاق مع التطبيقات العادية."</string>
<string name="permlab_bindDeviceAdmin" msgid="8704986163711455010">"التفاعل مع مشرف الجهاز"</string>
<string name="permdesc_bindDeviceAdmin" msgid="569715419543907930">"للسماح للمالك بإرسال الأهداف إلى أحد مشرفي الجهاز. لن تكون هناك حاجة إليه مطلقًا مع التطبيقات العادية."</string>
<string name="permlab_bindTvInput" msgid="5601264742478168987">"الالتزام بإدخال التلفزيون"</string>
@@ -742,6 +742,8 @@
<string name="permdesc_bindNotificationListenerService" msgid="985697918576902986">"يتيح للمالك الربط بواجهة المستوى العلوي لخدمة تلقّي الإشعارات الصوتية. ولن تكون هناك حاجة إليه مطلقًا مع التطبيقات العادية."</string>
<string name="permlab_bindConditionProviderService" msgid="1180107672332704641">"الربط بخدمة موفر الحالة"</string>
<string name="permdesc_bindConditionProviderService" msgid="1680513931165058425">"للسماح للمالك بالربط بواجهة المستوى العلوي لخدمة موفر الحالة. لن تكون هناك حاجة إلى هذا الإعداد مطلقًا مع التطبيقات العادية."</string>
+ <string name="permlab_bindMediaRouteService" msgid="6637740382272686835">"الربط بخدمة توجيه الوسائط"</string>
+ <string name="permdesc_bindMediaRouteService" msgid="6436655024972496687">"للسماح للمالك بالربط بواجهة المستوى العلوي لخدمة توجيه الوسائط. لن تكون هناك حاجة إلى هذا الإعداد مطلقًا مع التطبيقات العادية."</string>
<string name="permlab_bindDreamService" msgid="4153646965978563462">"الالتزام بخدمة dream"</string>
<string name="permdesc_bindDreamService" msgid="7325825272223347863">"للسماح للمالك بالالتزام بواجهة المستوى العلوي لخدمة dream. لن تكون هناك حاجة إليه مطلقًا مع التطبيقات العادية."</string>
<string name="permlab_invokeCarrierSetup" msgid="3699600833975117478">"استدعاء تطبيق التهيئة الذي يوفره مشغل شبكة الجوال"</string>
@@ -1283,6 +1285,9 @@
<skip />
<string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"تعذر الاتصال بـ Wi-Fi"</string>
<string name="wifi_watchdog_network_disabled_detailed" msgid="5548780776418332675">" لديها اتصال إنترنت رديء."</string>
+ <string name="wifi_connect_alert_title" msgid="8455846016001810172">"هل تريد السماح بالاتصال؟"</string>
+ <string name="wifi_connect_alert_message" msgid="8930084523889618078">"%1$s يرغب في الاتصال بـ %2$s"</string>
+ <string name="wifi_connect_default_application" msgid="7143109390475484319">"تطبيق"</string>
<string name="wifi_p2p_dialog_title" msgid="97611782659324517">"اتصال Wi-Fi مباشر"</string>
<string name="wifi_p2p_turnon_message" msgid="2909250942299627244">"ابدأ Wi-Fi Direct. يؤدي هذا إلى إيقاف عميل/نقطة اتصال Wi-Fi."</string>
<string name="wifi_p2p_failed_message" msgid="3763669677935623084">"تعذر بدء Wi-Fi Direct."</string>
diff --git a/core/res/res/values-bg/strings.xml b/core/res/res/values-bg/strings.xml
index b0a25e9..f6975c6 100644
--- a/core/res/res/values-bg/strings.xml
+++ b/core/res/res/values-bg/strings.xml
@@ -41,8 +41,6 @@
<string name="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g> сек"</string>
<string name="durationSecond" msgid="985669622276420331">"<xliff:g id="SECONDS">%1$d</xliff:g> сек"</string>
<string name="untitled" msgid="4638956954852782576">"<Без заглавие>"</string>
- <string name="ellipsis" msgid="7899829516048813237">"…"</string>
- <string name="ellipsis_two_dots" msgid="1228078994866030736">".."</string>
<string name="emptyPhoneNumber" msgid="7694063042079676517">"(Няма телефонен номер)"</string>
<string name="unknownName" msgid="2277556546742746522">"(Неизвестно)"</string>
<string name="defaultVoiceMailAlphaTag" msgid="2660020990097733077">"Гласова поща"</string>
@@ -415,6 +413,8 @@
<string name="permdesc_bindRemoteDisplay" msgid="1261242718727295981">"Разрешава на притежателя да се свърже с интерфейса от първо ниво на отдалечен екран. Нормалните приложения би трябвало никога да не се нуждаят от това."</string>
<string name="permlab_bindRemoteViews" msgid="5697987759897367099">"обвързване с услуга за приспособления"</string>
<string name="permdesc_bindRemoteViews" msgid="4717987810137692572">"Разрешава на притежателя да се обвърже с интерфейса от най-високото ниво на услуга за приспособления. Нормалните приложения би трябвало никога да не се нуждаят от това."</string>
+ <string name="permlab_bindRouteProvider" msgid="4869394607915096847">"свързване с услуга за предоставяне на маршрути"</string>
+ <string name="permdesc_bindRouteProvider" msgid="4703804520859960329">"Разрешава на собственика да се свързва с всички регистрирани доставчици на маршрути. Нормалните приложения би трябвало никога да не се нуждаят от това."</string>
<string name="permlab_bindDeviceAdmin" msgid="8704986163711455010">"взаимодействие с администратор на устройството"</string>
<string name="permdesc_bindDeviceAdmin" msgid="569715419543907930">"Разрешава на притежателя да изпраща намерения до администратор на устройството. Нормалните приложения би трябвало никога да не се нуждаят от това."</string>
<string name="permlab_bindTvInput" msgid="5601264742478168987">"свързване към вход на телевизор"</string>
@@ -742,6 +742,8 @@
<string name="permdesc_bindNotificationListenerService" msgid="985697918576902986">"Разрешава на притежателя да се обвърже с интерфейса от първо ниво на услуга за слушател на известия. Нормалните приложения не би трябвало никога да се нуждаят от това."</string>
<string name="permlab_bindConditionProviderService" msgid="1180107672332704641">"свързване с услуга за предоставяне на условия"</string>
<string name="permdesc_bindConditionProviderService" msgid="1680513931165058425">"Разрешава на притежателя да се свърже с интерфейса от най-високото ниво на услуга за предоставяне на условия. Нормалните приложения би трябвало никога да не се нуждаят от това."</string>
+ <string name="permlab_bindMediaRouteService" msgid="6637740382272686835">"свързване с услуга за маршрутизиране на мултимедия"</string>
+ <string name="permdesc_bindMediaRouteService" msgid="6436655024972496687">"Разрешава на притежателя да се свърже с интерфейса от най-високото ниво на услуга за маршрутизиране на мултимедия. Нормалните приложения би трябвало никога да не се нуждаят от това."</string>
<string name="permlab_bindDreamService" msgid="4153646965978563462">"свързване с услуга за „мечти“"</string>
<string name="permdesc_bindDreamService" msgid="7325825272223347863">"Разрешава на притежателя да се свърже с интерфейса от най-високото ниво на услуга за „мечти“. Нормалните приложения би трябвало никога да не се нуждаят от това."</string>
<string name="permlab_invokeCarrierSetup" msgid="3699600833975117478">"извикване на предоставеното от оператора приложение за конфигуриране"</string>
@@ -1283,6 +1285,9 @@
<skip />
<string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"Не можа да се свърже с Wi-Fi"</string>
<string name="wifi_watchdog_network_disabled_detailed" msgid="5548780776418332675">" има лоша връзка с интернет."</string>
+ <string name="wifi_connect_alert_title" msgid="8455846016001810172">"Да се разреши ли връзката?"</string>
+ <string name="wifi_connect_alert_message" msgid="8930084523889618078">"%1$s иска да установи връзка с/ъс %2$s"</string>
+ <string name="wifi_connect_default_application" msgid="7143109390475484319">"Приложение"</string>
<string name="wifi_p2p_dialog_title" msgid="97611782659324517">"Wi-Fi Direct"</string>
<string name="wifi_p2p_turnon_message" msgid="2909250942299627244">"Стартиране на Wi-Fi Direct. Това ще изключи клиентската програма/точката за достъп до Wi-Fi."</string>
<string name="wifi_p2p_failed_message" msgid="3763669677935623084">"Wi-Fi Direct не можа да се стартира."</string>
diff --git a/core/res/res/values-bn-rBD/strings.xml b/core/res/res/values-bn-rBD/strings.xml
index 8c6a9b7..f5ddb8a 100644
--- a/core/res/res/values-bn-rBD/strings.xml
+++ b/core/res/res/values-bn-rBD/strings.xml
@@ -41,8 +41,6 @@
<string name="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g> সেকেন্ড"</string>
<string name="durationSecond" msgid="985669622276420331">"<xliff:g id="SECONDS">%1$d</xliff:g> সেকেন্ড"</string>
<string name="untitled" msgid="4638956954852782576">"<শিরোনামহীন>"</string>
- <string name="ellipsis" msgid="7899829516048813237">"…"</string>
- <string name="ellipsis_two_dots" msgid="1228078994866030736">"‥"</string>
<string name="emptyPhoneNumber" msgid="7694063042079676517">"(কোনো ফোন নম্বর নেই)"</string>
<string name="unknownName" msgid="2277556546742746522">"(অজানা)"</string>
<string name="defaultVoiceMailAlphaTag" msgid="2660020990097733077">"ভয়েসমেল"</string>
@@ -415,6 +413,8 @@
<string name="permdesc_bindRemoteDisplay" msgid="1261242718727295981">"ধারককে, একটি দূরবর্তী প্রদর্শনের উচ্চ স্তরের ইন্টারফেসে জুড়তে অনুমতি দেয়। সধারণ অ্যাপ্লিকেশানগুলির জন্য কখনই প্রয়োজন হয় না৷"</string>
<string name="permlab_bindRemoteViews" msgid="5697987759897367099">"একটি উইজেট পরিষেবাতে সংলগ্ন করে"</string>
<string name="permdesc_bindRemoteViews" msgid="4717987810137692572">"ধারককে, একটি উইজেট পরিষেবার উচ্চ স্তরের ইন্টারফেসে জুড়তে অনুমতি দেয়৷ সধারণ অ্যাপ্লিকেশানগুলির জন্য কখনই প্রয়োজন হয় না৷"</string>
+ <string name="permlab_bindRouteProvider" msgid="4869394607915096847">"একটি রুট প্রদানকারীর পরিষেবা বাঁধাই করে"</string>
+ <string name="permdesc_bindRouteProvider" msgid="4703804520859960329">"ধারককে, কোনো নিবন্ধিত রুট প্রদানকারীকে বাঁধাই করার অনুমতি দেয়৷ সধারণ অ্যাপ্লিকেশানগুলির জন্য কখনই প্রয়োজন হয় না৷"</string>
<string name="permlab_bindDeviceAdmin" msgid="8704986163711455010">"একটি ডিভাইস প্রশাসকের সাথে ইন্টারঅ্যাক্ট করে"</string>
<string name="permdesc_bindDeviceAdmin" msgid="569715419543907930">"ধারককে, একটি ডিভাইস প্রশাসকে ইন্টেন্টগুলি পাঠানোর অনুমতি দেয়৷ সধারণ অ্যাপ্লিকেশানগুলির জন্য কখনই প্রয়োজন হয় না৷"</string>
<string name="permlab_bindTvInput" msgid="5601264742478168987">"টিভি ইনপুট বাঁধাই করে"</string>
@@ -742,6 +742,8 @@
<string name="permdesc_bindNotificationListenerService" msgid="985697918576902986">"ধারককে, একটি বিজ্ঞপ্তি শ্রোতা পরিষেবার উচ্চ স্তরের ইন্টারফেসে জুড়তে অনুমতি দেয়৷ সধারণ অ্যাপ্লিকেশানগুলির জন্য কখনই প্রয়োজন হয় না৷"</string>
<string name="permlab_bindConditionProviderService" msgid="1180107672332704641">"একটি শর্ত প্রদানকারীর পরিষেবা বাঁধাই করে"</string>
<string name="permdesc_bindConditionProviderService" msgid="1680513931165058425">"ধারককে, একটি শর্ত প্রদানকারী পরিষেবার উচ্চ স্তরের ইন্টারফেসে জুড়তে অনুমতি দেয়৷ সধারণ অ্যাপ্লিকেশানগুলির জন্য কখনই প্রয়োজন হয় না৷"</string>
+ <string name="permlab_bindMediaRouteService" msgid="6637740382272686835">"একটি মিডিয়া রুট পরিষেবায় জুড়ুন"</string>
+ <string name="permdesc_bindMediaRouteService" msgid="6436655024972496687">"ধারককে একটি মিডিয়া রুট পরিষেবার উচ্চ স্তরের ইন্টারফেসে জুড়তে অনুমতি দেয়। সাধারণ অ্যাপ্লিকেশানগুলির জন্য কখনোই প্রয়োজন হয় না।"</string>
<string name="permlab_bindDreamService" msgid="4153646965978563462">"একটি স্বপ্নের পরিষেবার সাথে যুক্ত হন"</string>
<string name="permdesc_bindDreamService" msgid="7325825272223347863">"ধারককে, একটি স্বপ্নের পরিষেবার উচ্চ স্তরের ইন্টারফেসে জুড়তে অনুমতি দেয়৷ সধারণ অ্যাপ্লিকেশানগুলির জন্য কখনই প্রয়োজন হয় না৷"</string>
<string name="permlab_invokeCarrierSetup" msgid="3699600833975117478">"ক্যারিয়ারের প্রদেয় কনফিগারেশন অ্যাপ্লিকেশানকে দিয়ে কাজ করায়"</string>
@@ -1283,6 +1285,9 @@
<skip />
<string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"Wi-Fi এর সাথে সংযোগ করা যায়নি"</string>
<string name="wifi_watchdog_network_disabled_detailed" msgid="5548780776418332675">" একটি দুর্বল ইন্টারনেট সংযোগ রয়েছে৷"</string>
+ <string name="wifi_connect_alert_title" msgid="8455846016001810172">"সংযোগের মঞ্জুরি দেবেন?"</string>
+ <string name="wifi_connect_alert_message" msgid="8930084523889618078">"%1$s %2$s এর সাথে সংযোগ করতে চায়"</string>
+ <string name="wifi_connect_default_application" msgid="7143109390475484319">"একটি অ্যাপ্লিকেশান"</string>
<string name="wifi_p2p_dialog_title" msgid="97611782659324517">"Wi-Fi ডাইরেক্ট"</string>
<string name="wifi_p2p_turnon_message" msgid="2909250942299627244">"Wi-Fi ডাইরেক্ট আরম্ভ করুন৷ এটি Wi-Fi client/hotspot কে বন্ধ করবে৷"</string>
<string name="wifi_p2p_failed_message" msgid="3763669677935623084">"Wi-Fi ডাইরেক্ট শুরু করা যায়নি৷"</string>
@@ -1776,8 +1781,7 @@
<string name="lock_to_app_unlock_password" msgid="6380979775916974414">"আনপিন করার আগে পাসওয়ার্ড চান"</string>
<string name="battery_saver_description" msgid="2510530476513605742">"ব্যাটারির আয়ু বাড়াতে সহায়তার জন্য, ব্যাটারি সঞ্চয়কারী আপনার ডিভাইসের কার্য-সম্পাদনা কমিয়ে আনবে এবং কম্পন ও পশ্চাদভূমি ডেটাকে সীমিত করবে। ইমেল, বার্তাপ্রেরণ ও অন্যান্য অ্যাপ্লিকেশান, যেগুলি সিঙ্ক হওয়ার উপর নির্ভরশীল সেগুলিকে আপনি না খোলা পর্যন্ত সেগুলি আপডেট নাও হতে পারে।\n\nআপনার ডিভাইস চার্জ হওয়ার সময় ব্যাটারি সঞ্চয়কারী স্বয়ংক্রিয়ভাবে বন্ধ হয়ে যাবে।"</string>
<string name="downtime_condition_summary" msgid="8761776337475705749">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g>টার সময়ে আপনার ডাউনটাইম শেষ হওয়া পর্যন্ত"</string>
- <!-- no translation found for downtime_condition_line_one (8762708714645352010) -->
- <skip />
+ <string name="downtime_condition_line_one" msgid="8762708714645352010">"আপনার ডাউনটাইম শেষ না হওয়া পর্যন্ত"</string>
<plurals name="zen_mode_duration_minutes_summary">
<item quantity="one" msgid="3177683545388923234">"এক মিনিটের জন্য (<xliff:g id="FORMATTEDTIME">%2$s</xliff:g> পর্যন্ত)"</item>
<item quantity="other" msgid="2787867221129368935">"%1$d মিনিটের জন্য (<xliff:g id="FORMATTEDTIME">%2$s</xliff:g> পর্যন্ত)"</item>
@@ -1797,8 +1801,6 @@
<string name="zen_mode_until" msgid="7336308492289875088">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g> পর্যন্ত"</string>
<string name="zen_mode_forever" msgid="4316804956488785559">"অনির্দিষ্টভাবে"</string>
<string name="toolbar_collapse_description" msgid="2821479483960330739">"সঙ্কুচিত করুন"</string>
- <!-- no translation found for zen_mode_next_alarm_summary (5915140424683747372) -->
- <skip />
- <!-- no translation found for zen_mode_next_alarm_line_one (5537042951553420916) -->
- <skip />
+ <string name="zen_mode_next_alarm_summary" msgid="5915140424683747372">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g> এ পরবর্তী অ্যালার্ম পর্যন্ত"</string>
+ <string name="zen_mode_next_alarm_line_one" msgid="5537042951553420916">"পরবর্তী অ্যালার্ম পর্যন্ত"</string>
</resources>
diff --git a/core/res/res/values-ca/strings.xml b/core/res/res/values-ca/strings.xml
index 93c8389..725abe3 100644
--- a/core/res/res/values-ca/strings.xml
+++ b/core/res/res/values-ca/strings.xml
@@ -41,8 +41,6 @@
<string name="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g> s"</string>
<string name="durationSecond" msgid="985669622276420331">"<xliff:g id="SECONDS">%1$d</xliff:g> s"</string>
<string name="untitled" msgid="4638956954852782576">"<Sense títol>"</string>
- <string name="ellipsis" msgid="7899829516048813237">"…"</string>
- <string name="ellipsis_two_dots" msgid="1228078994866030736">"‥"</string>
<string name="emptyPhoneNumber" msgid="7694063042079676517">"(Sense número de telèfon)"</string>
<string name="unknownName" msgid="2277556546742746522">"(Desconegut)"</string>
<string name="defaultVoiceMailAlphaTag" msgid="2660020990097733077">"Correu de veu"</string>
@@ -415,6 +413,8 @@
<string name="permdesc_bindRemoteDisplay" msgid="1261242718727295981">"Permet que el titular es vinculi a la interfície de nivell superior d\'una pantalla remota. No s\'hauria de necessitar mai per a les aplicacions normals."</string>
<string name="permlab_bindRemoteViews" msgid="5697987759897367099">"vincula a un servei de widget"</string>
<string name="permdesc_bindRemoteViews" msgid="4717987810137692572">"Permet que el titular vinculi a la interfície de nivell superior d\'un servei de widget. No s\'hauria de necessitar mai per a les aplicacions normals."</string>
+ <string name="permlab_bindRouteProvider" msgid="4869394607915096847">"establir vincles amb un servei d\'aprovisionament de rutes"</string>
+ <string name="permdesc_bindRouteProvider" msgid="4703804520859960329">"Permet que el titular estableixi vincles amb els proveïdors de rutes registrats. No hauria de ser mai necessari per a les aplicacions normals."</string>
<string name="permlab_bindDeviceAdmin" msgid="8704986163711455010">"interactuar amb un administrador del dispositiu"</string>
<string name="permdesc_bindDeviceAdmin" msgid="569715419543907930">"Permet que el titular enviï intents a un administrador del sistema. No s\'hauria de necessitar mai per a les aplicacions normals."</string>
<string name="permlab_bindTvInput" msgid="5601264742478168987">"Vinculació a una entrada de televisor"</string>
@@ -742,6 +742,8 @@
<string name="permdesc_bindNotificationListenerService" msgid="985697918576902986">"Permet que el titular vinculi la interfície de nivell superior d\'un servei oient de notificacions. No s\'hauria de necessitar mai per a les aplicacions normals."</string>
<string name="permlab_bindConditionProviderService" msgid="1180107672332704641">"enllaçar amb el servei de proveïdor de condicions"</string>
<string name="permdesc_bindConditionProviderService" msgid="1680513931165058425">"Permet enllaçar amb la interfície de nivell superior d\'un servei de proveïdor de condicions. No ha de ser mai necessari per a aplicacions normals."</string>
+ <string name="permlab_bindMediaRouteService" msgid="6637740382272686835">"vincular-se amb un servei de rutes multimèdia"</string>
+ <string name="permdesc_bindMediaRouteService" msgid="6436655024972496687">"Permet que el titular es vinculi amb la interfície de nivell superior d\'un servei de rutes multimèdia. No ha de ser mai necessari per a aplicacions normals."</string>
<string name="permlab_bindDreamService" msgid="4153646965978563462">"enllaçar amb un servei en repòs"</string>
<string name="permdesc_bindDreamService" msgid="7325825272223347863">"Permet enllaçar amb la interfície de nivell superior d\'un servei en repòs. No hauria de ser mai necessari per a aplicacions normals."</string>
<string name="permlab_invokeCarrierSetup" msgid="3699600833975117478">"invoca l\'aplicació de configuració proporcionada per l\'operador"</string>
@@ -1283,6 +1285,9 @@
<skip />
<string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"No s\'ha pogut connectar a la Wi-Fi"</string>
<string name="wifi_watchdog_network_disabled_detailed" msgid="5548780776418332675">" té una mala connexió a Internet."</string>
+ <string name="wifi_connect_alert_title" msgid="8455846016001810172">"Vols permetre la connexió?"</string>
+ <string name="wifi_connect_alert_message" msgid="8930084523889618078">"%1$s vol connectar amb %2$s."</string>
+ <string name="wifi_connect_default_application" msgid="7143109390475484319">"Una aplicació"</string>
<string name="wifi_p2p_dialog_title" msgid="97611782659324517">"Wi-Fi Direct"</string>
<string name="wifi_p2p_turnon_message" msgid="2909250942299627244">"Inicia Wi-Fi Direct. Això desactivarà el client/la zona Wi-Fi."</string>
<string name="wifi_p2p_failed_message" msgid="3763669677935623084">"No s\'ha pogut iniciar Wi-Fi Direct."</string>
diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml
index 68e5f1c..074e8e4 100644
--- a/core/res/res/values-cs/strings.xml
+++ b/core/res/res/values-cs/strings.xml
@@ -41,8 +41,6 @@
<string name="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g> s"</string>
<string name="durationSecond" msgid="985669622276420331">"<xliff:g id="SECONDS">%1$d</xliff:g> s"</string>
<string name="untitled" msgid="4638956954852782576">"<Bez názvu>"</string>
- <string name="ellipsis" msgid="7899829516048813237">"…"</string>
- <string name="ellipsis_two_dots" msgid="1228078994866030736">".."</string>
<string name="emptyPhoneNumber" msgid="7694063042079676517">"(žádné telefonní číslo)"</string>
<string name="unknownName" msgid="2277556546742746522">"(Neznámé)"</string>
<string name="defaultVoiceMailAlphaTag" msgid="2660020990097733077">"Hlasová schránka"</string>
@@ -415,6 +413,8 @@
<string name="permdesc_bindRemoteDisplay" msgid="1261242718727295981">"Umožňuje držiteli připojit se k vysokoúrovňovému rozhraní vzdáleného displeje. Běžné aplikace by toto oprávnění neměly nikdy potřebovat."</string>
<string name="permlab_bindRemoteViews" msgid="5697987759897367099">"navázat se na službu widgetu"</string>
<string name="permdesc_bindRemoteViews" msgid="4717987810137692572">"Umožňuje držiteli navázat se na nejvyšší úroveň služby widgetu. Běžné aplikace by toto oprávnění neměly nikdy požadovat."</string>
+ <string name="permlab_bindRouteProvider" msgid="4869394607915096847">"navázání na službu poskytovatele tras"</string>
+ <string name="permdesc_bindRouteProvider" msgid="4703804520859960329">"Umožňuje držiteli navázat se na libovolného poskytovatele registrovaných tras. Běžné aplikace by toto oprávnění neměly nikdy potřebovat."</string>
<string name="permlab_bindDeviceAdmin" msgid="8704986163711455010">"komunikovat se správcem zařízení"</string>
<string name="permdesc_bindDeviceAdmin" msgid="569715419543907930">"Umožňuje držiteli oprávnění odesílat informace správci zařízení. Běžné aplikace by toto oprávnění neměly nikdy požadovat."</string>
<string name="permlab_bindTvInput" msgid="5601264742478168987">"navázání na televizní vstup"</string>
@@ -742,6 +742,8 @@
<string name="permdesc_bindNotificationListenerService" msgid="985697918576902986">"Umožňuje držiteli navázat se na nejvyšší úroveň služby pro poslouchání oznámení. Běžné aplikace by toto oprávnění neměly nikdy požadovat."</string>
<string name="permlab_bindConditionProviderService" msgid="1180107672332704641">"navázání na službu poskytovatele podmínky"</string>
<string name="permdesc_bindConditionProviderService" msgid="1680513931165058425">"Umožňuje držiteli navázat se na nejvyšší úroveň rozhraní služby poskytovatele podmínky. Běžné aplikace by toto oprávnění neměly nikdy potřebovat."</string>
+ <string name="permlab_bindMediaRouteService" msgid="6637740382272686835">"navázání na službu směrování médií"</string>
+ <string name="permdesc_bindMediaRouteService" msgid="6436655024972496687">"Umožňuje držiteli navázat se na nejvyšší úroveň rozhraní služby směrování médií. Běžné aplikace by toto oprávnění neměly nikdy potřebovat."</string>
<string name="permlab_bindDreamService" msgid="4153646965978563462">"navázat se na službu spořiče"</string>
<string name="permdesc_bindDreamService" msgid="7325825272223347863">"Umožňuje navázání na nejvyšší úroveň služby spořiče. Běžné aplikace by toto oprávnění neměly nikdy potřebovat."</string>
<string name="permlab_invokeCarrierSetup" msgid="3699600833975117478">"vyvolat konfigurační aplikaci poskytnutou operátorem"</string>
@@ -1283,6 +1285,9 @@
<skip />
<string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"Připojení k síti Wi-Fi se nezdařilo"</string>
<string name="wifi_watchdog_network_disabled_detailed" msgid="5548780776418332675">" má pomalé připojení k internetu."</string>
+ <string name="wifi_connect_alert_title" msgid="8455846016001810172">"Povolit připojení?"</string>
+ <string name="wifi_connect_alert_message" msgid="8930084523889618078">"%1$s se chce připojit k %2$s"</string>
+ <string name="wifi_connect_default_application" msgid="7143109390475484319">"Aplikace"</string>
<string name="wifi_p2p_dialog_title" msgid="97611782659324517">"Přímé připojení sítě Wi-Fi"</string>
<string name="wifi_p2p_turnon_message" msgid="2909250942299627244">"Spustit přímé připojení sítě Wi-Fi. Tato možnost vypne provoz sítě Wi-Fi v režimu klient/hotspot."</string>
<string name="wifi_p2p_failed_message" msgid="3763669677935623084">"Přímé připojení sítě Wi-Fi se nepodařilo spustit."</string>
diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml
index 08b9aa5..8dc9245 100644
--- a/core/res/res/values-da/strings.xml
+++ b/core/res/res/values-da/strings.xml
@@ -41,8 +41,6 @@
<string name="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g> sek."</string>
<string name="durationSecond" msgid="985669622276420331">"<xliff:g id="SECONDS">%1$d</xliff:g> sek."</string>
<string name="untitled" msgid="4638956954852782576">"<Uden titel>"</string>
- <string name="ellipsis" msgid="7899829516048813237">"…"</string>
- <string name="ellipsis_two_dots" msgid="1228078994866030736">".."</string>
<string name="emptyPhoneNumber" msgid="7694063042079676517">"(Intet telefonnummer)"</string>
<string name="unknownName" msgid="2277556546742746522">"(Ukendt)"</string>
<string name="defaultVoiceMailAlphaTag" msgid="2660020990097733077">"Telefonsvarer"</string>
@@ -415,6 +413,8 @@
<string name="permdesc_bindRemoteDisplay" msgid="1261242718727295981">"Tillader, at brugeren kan foretage en binding til grænsefladens øverste niveau på en ekstern skærm. Bør aldrig være nødvendigt til almindelige apps."</string>
<string name="permlab_bindRemoteViews" msgid="5697987759897367099">"forpligt til en widgettjeneste"</string>
<string name="permdesc_bindRemoteViews" msgid="4717987810137692572">"Tillader, at brugeren kan forpligte sig til en grænseflade for en widgettjeneste på øverste niveau. Bør aldrig være nødvendigt til almindelige apps."</string>
+ <string name="permlab_bindRouteProvider" msgid="4869394607915096847">"oprette tilknytning til en ruteudbydertjeneste"</string>
+ <string name="permdesc_bindRouteProvider" msgid="4703804520859960329">"Tillader, at indehaveren opretter tilknytninger til registrerede ruteudbydere. Dette bør aldrig være nødvendigt for normale apps."</string>
<string name="permlab_bindDeviceAdmin" msgid="8704986163711455010">"kommunikere med en enhedsadministrator"</string>
<string name="permdesc_bindDeviceAdmin" msgid="569715419543907930">"Tillader, at brugeren kan sende hensigter til en enhedsadministrator. Dette bør aldrig være nødvendigt for almindelige apps."</string>
<string name="permlab_bindTvInput" msgid="5601264742478168987">"knyt til en tv-indgang"</string>
@@ -742,6 +742,8 @@
<string name="permdesc_bindNotificationListenerService" msgid="985697918576902986">"Tillader brugeren at forpligte sig til en underretningslyttertjenestes grænseflade på øverste niveau. Bør aldrig være nødvendigt til almindelige apps."</string>
<string name="permlab_bindConditionProviderService" msgid="1180107672332704641">"oprette binding til en tjeneste til formidling af betingelser"</string>
<string name="permdesc_bindConditionProviderService" msgid="1680513931165058425">"Tillader, at brugeren opretter en binding til det øverste niveau af grænsefladen i en tjeneste til formidling af betingelser. Dette bør aldrig være nødvendigt for almindelige apps."</string>
+ <string name="permlab_bindMediaRouteService" msgid="6637740382272686835">"opret binding til en medierutetjeneste"</string>
+ <string name="permdesc_bindMediaRouteService" msgid="6436655024972496687">"Tillader, at brugeren opretter en binding til det øverste niveau af grænsefladen i en medierutetjeneste. Dette bør aldrig være nødvendigt for almindelige apps."</string>
<string name="permlab_bindDreamService" msgid="4153646965978563462">"fastlås til en drømmetjeneste"</string>
<string name="permdesc_bindDreamService" msgid="7325825272223347863">"Tillader, at indehaveren fastlåser det øverste niveau af brugergrænsefladen for en drømmetjeneste. Dette bør aldrig være nødvendigt for almindelige apps."</string>
<string name="permlab_invokeCarrierSetup" msgid="3699600833975117478">"aktivere konfigurationsappen, der leveres af mobilselskabet"</string>
@@ -1283,6 +1285,9 @@
<skip />
<string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"Kunne ikke oprette forbindelse til Wi-Fi"</string>
<string name="wifi_watchdog_network_disabled_detailed" msgid="5548780776418332675">" har en dårlig internetforbindelse."</string>
+ <string name="wifi_connect_alert_title" msgid="8455846016001810172">"Vil du tillade denne forbindelse?"</string>
+ <string name="wifi_connect_alert_message" msgid="8930084523889618078">"%1$s vil gerne oprette forbindelse til %2$s"</string>
+ <string name="wifi_connect_default_application" msgid="7143109390475484319">"En applikation"</string>
<string name="wifi_p2p_dialog_title" msgid="97611782659324517">"Wi-Fi Direct"</string>
<string name="wifi_p2p_turnon_message" msgid="2909250942299627244">"Start Wi-Fi Direct. Dette slår Wi-Fi-klient/hotspot fra."</string>
<string name="wifi_p2p_failed_message" msgid="3763669677935623084">"Wi-Fi Direct kunne ikke startes."</string>
@@ -1776,8 +1781,7 @@
<string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Bed om adgangskode inden frigørelse"</string>
<string name="battery_saver_description" msgid="2510530476513605742">"For at forbedre batteriets levetid reducerer batterisparefunktionen enhedens ydeevne og begrænser vibrationer og de fleste baggrundsdata. E-mail, chat og andre apps, der benytter synkronisering, opdateres ikke, medmindre du åbner dem.\n\nBatterisparefunktionen deaktiveres automatisk, når enheden oplades."</string>
<string name="downtime_condition_summary" msgid="8761776337475705749">"Indtil din nedetid slutter kl. <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
- <!-- no translation found for downtime_condition_line_one (8762708714645352010) -->
- <skip />
+ <string name="downtime_condition_line_one" msgid="8762708714645352010">"Indtil nedetiden ophører"</string>
<plurals name="zen_mode_duration_minutes_summary">
<item quantity="one" msgid="3177683545388923234">"I ét minut (indtil <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
<item quantity="other" msgid="2787867221129368935">"I %1$d minutter (indtil <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
@@ -1797,8 +1801,6 @@
<string name="zen_mode_until" msgid="7336308492289875088">"Indtil <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
<string name="zen_mode_forever" msgid="4316804956488785559">"Uendeligt"</string>
<string name="toolbar_collapse_description" msgid="2821479483960330739">"Skjul"</string>
- <!-- no translation found for zen_mode_next_alarm_summary (5915140424683747372) -->
- <skip />
- <!-- no translation found for zen_mode_next_alarm_line_one (5537042951553420916) -->
- <skip />
+ <string name="zen_mode_next_alarm_summary" msgid="5915140424683747372">"Indtil næste alarm kl. <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
+ <string name="zen_mode_next_alarm_line_one" msgid="5537042951553420916">"Indtil næste alarm"</string>
</resources>
diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml
index 135a7a63..6547844 100644
--- a/core/res/res/values-de/strings.xml
+++ b/core/res/res/values-de/strings.xml
@@ -41,8 +41,6 @@
<string name="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g> Sek."</string>
<string name="durationSecond" msgid="985669622276420331">"<xliff:g id="SECONDS">%1$d</xliff:g> Sek."</string>
<string name="untitled" msgid="4638956954852782576">"<Unbenannt>"</string>
- <string name="ellipsis" msgid="7899829516048813237">"…"</string>
- <string name="ellipsis_two_dots" msgid="1228078994866030736">"‥"</string>
<string name="emptyPhoneNumber" msgid="7694063042079676517">"(Keine Telefonnummer)"</string>
<string name="unknownName" msgid="2277556546742746522">"(Unbekannt)"</string>
<string name="defaultVoiceMailAlphaTag" msgid="2660020990097733077">"Mailbox"</string>
@@ -415,6 +413,8 @@
<string name="permdesc_bindRemoteDisplay" msgid="1261242718727295981">"Ermöglicht dem Halter, sich an die Oberfläche eines Remote-Displays auf oberster Ebene zu binden. Sollte für normale Apps nie benötigt werden."</string>
<string name="permlab_bindRemoteViews" msgid="5697987759897367099">"An einen Widget-Dienst binden"</string>
<string name="permdesc_bindRemoteViews" msgid="4717987810137692572">"Ermöglicht dem Halter, sich an die Oberfläche eines Widget-Dienstes auf oberster Ebene zu binden. Sollte nie für normale Apps benötigt werden."</string>
+ <string name="permlab_bindRouteProvider" msgid="4869394607915096847">"An Routenanbieterdienst binden"</string>
+ <string name="permdesc_bindRouteProvider" msgid="4703804520859960329">"Ermöglicht dem Inhaber die Bindung an registrierte Routenanbieter. Sollte für normale Apps nicht erforderlich sein"</string>
<string name="permlab_bindDeviceAdmin" msgid="8704986163711455010">"Interaktion mit einem Geräteadministrator"</string>
<string name="permdesc_bindDeviceAdmin" msgid="569715419543907930">"Ermöglicht dem Halter, Intents an einen Geräteadministrator zu senden. Sollte nie für normale Apps benötigt werden."</string>
<string name="permlab_bindTvInput" msgid="5601264742478168987">"An eine TV-Eingabe binden"</string>
@@ -742,6 +742,8 @@
<string name="permdesc_bindNotificationListenerService" msgid="985697918576902986">"Ermöglicht dem Inhaber, sich an die Oberfläche der obersten Ebene eines Benachrichtigungs-Listener-Dienstes zu binden. Sollte nie für normale Apps benötigt werden."</string>
<string name="permlab_bindConditionProviderService" msgid="1180107672332704641">"An einen Bedingungsproviderdienst binden"</string>
<string name="permdesc_bindConditionProviderService" msgid="1680513931165058425">"Ermöglicht dem Inhaber, sich an die Oberfläche eines Bedingungsproviderdienstes auf oberster Ebene zu binden. Für normale Apps sollte dies nie erforderlich sein."</string>
+ <string name="permlab_bindMediaRouteService" msgid="6637740382272686835">"An Mediarouting-Dienst binden"</string>
+ <string name="permdesc_bindMediaRouteService" msgid="6436655024972496687">"Ermöglicht dem Inhaber die Bindung an die Oberfläche eines Mediarouting-Dienstes auf oberster Ebene. Für normale Apps sollte dies nie erforderlich sein."</string>
<string name="permlab_bindDreamService" msgid="4153646965978563462">"An Dream-Dienst binden"</string>
<string name="permdesc_bindDreamService" msgid="7325825272223347863">"Ermöglicht der App, sich an die Oberfläche eines Dream-Dienstes auf oberster Ebene zu binden. Für normale Apps sollte dies nie erforderlich sein."</string>
<string name="permlab_invokeCarrierSetup" msgid="3699600833975117478">"Vom Mobilfunkanbieter bereitgestellte Konfigurations-App aufrufen"</string>
@@ -1283,6 +1285,9 @@
<skip />
<string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"Es konnte keine WLAN-Verbindung hergestellt werden."</string>
<string name="wifi_watchdog_network_disabled_detailed" msgid="5548780776418332675">" hat eine schlechte Internetverbindung."</string>
+ <string name="wifi_connect_alert_title" msgid="8455846016001810172">"Verbindung zulassen?"</string>
+ <string name="wifi_connect_alert_message" msgid="8930084523889618078">"%1$s möchte eine Verbindung mit %2$s herstellen."</string>
+ <string name="wifi_connect_default_application" msgid="7143109390475484319">"Eine App"</string>
<string name="wifi_p2p_dialog_title" msgid="97611782659324517">"Wi-Fi Direct"</string>
<string name="wifi_p2p_turnon_message" msgid="2909250942299627244">"Wi-Fi Direct-Betrieb starten. Hierdurch wird der WLAN-Client-/-Hotspot-Betrieb deaktiviert."</string>
<string name="wifi_p2p_failed_message" msgid="3763669677935623084">"Starten von Wi-Fi Direct nicht möglich"</string>
@@ -1776,8 +1781,7 @@
<string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Vor dem Beenden nach Passwort fragen"</string>
<string name="battery_saver_description" msgid="2510530476513605742">"Der Energiesparmodus hilft, den Akku zu schonen, indem er die Leistung des Geräts reduziert und die Vibrationsfunktion und die meisten Hintergrunddatenaktivitäten einschränkt. E-Mail-, Chat- und andere Apps, die die Synchronisierungsfunktion benötigen, werden möglicherweise nicht aktualisiert, bis Sie sie öffnen.\n\nDer Energiesparmodus endet automatisch, wenn Ihr Gerät aufgeladen wird."</string>
<string name="downtime_condition_summary" msgid="8761776337475705749">"Bis zum Ende der Downtime um <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
- <!-- no translation found for downtime_condition_line_one (8762708714645352010) -->
- <skip />
+ <string name="downtime_condition_line_one" msgid="8762708714645352010">"Bis zum Ende der Inaktivität"</string>
<plurals name="zen_mode_duration_minutes_summary">
<item quantity="one" msgid="3177683545388923234">"1 Minute (bis <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
<item quantity="other" msgid="2787867221129368935">"%1$d Minuten (bis <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
@@ -1797,8 +1801,6 @@
<string name="zen_mode_until" msgid="7336308492289875088">"Bis <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
<string name="zen_mode_forever" msgid="4316804956488785559">"Unbegrenzt"</string>
<string name="toolbar_collapse_description" msgid="2821479483960330739">"Minimieren"</string>
- <!-- no translation found for zen_mode_next_alarm_summary (5915140424683747372) -->
- <skip />
- <!-- no translation found for zen_mode_next_alarm_line_one (5537042951553420916) -->
- <skip />
+ <string name="zen_mode_next_alarm_summary" msgid="5915140424683747372">"Bis zum nächsten Weckruf um <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
+ <string name="zen_mode_next_alarm_line_one" msgid="5537042951553420916">"Bis zum nächsten Weckruf"</string>
</resources>
diff --git a/core/res/res/values-el/strings.xml b/core/res/res/values-el/strings.xml
index eacd3eb..8ee980a 100644
--- a/core/res/res/values-el/strings.xml
+++ b/core/res/res/values-el/strings.xml
@@ -41,8 +41,6 @@
<string name="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g> δευτ."</string>
<string name="durationSecond" msgid="985669622276420331">"<xliff:g id="SECONDS">%1$d</xliff:g> δευτ."</string>
<string name="untitled" msgid="4638956954852782576">"<Χωρίς τίτλο>"</string>
- <string name="ellipsis" msgid="7899829516048813237">"…"</string>
- <string name="ellipsis_two_dots" msgid="1228078994866030736">"‥"</string>
<string name="emptyPhoneNumber" msgid="7694063042079676517">"(Δεν υπάρχει τηλεφωνικός αριθμός)"</string>
<string name="unknownName" msgid="2277556546742746522">"(Άγνωστο)"</string>
<string name="defaultVoiceMailAlphaTag" msgid="2660020990097733077">"Αυτόματος τηλεφωνητής"</string>
@@ -415,6 +413,8 @@
<string name="permdesc_bindRemoteDisplay" msgid="1261242718727295981">"Επιτρέπει στον κάτοχο τη δέσμευση στη διεπαφή ανωτάτου επιπέδου μιας απομακρυσμένης οθόνης. Δεν απαιτείται ποτέ για κανονικές εφαρμογές."</string>
<string name="permlab_bindRemoteViews" msgid="5697987759897367099">"δέσμευση σε υπηρεσία γραφικών στοιχείων"</string>
<string name="permdesc_bindRemoteViews" msgid="4717987810137692572">"Επιτρέπει στον κάτοχο τη δέσμευση στη διεπαφή ανωτάτου επιπέδου μιας υπηρεσίας γραφικών στοιχείων. Δεν απαιτείται για κανονικές εφαρμογές."</string>
+ <string name="permlab_bindRouteProvider" msgid="4869394607915096847">"σύνδεση σε μια υπηρεσία παρόχου δρομολογητή"</string>
+ <string name="permdesc_bindRouteProvider" msgid="4703804520859960329">"Δίνει στον κάτοχο τη δυνατότητα σύνδεσης με οποιονδήποτε εγγεγραμμένο πάροχο δρομολογητή. Δεν απαιτείται ποτέ για κανονικές εφαρμογές."</string>
<string name="permlab_bindDeviceAdmin" msgid="8704986163711455010">"επικοινωνία με έναν διαχειριστή συσκευής"</string>
<string name="permdesc_bindDeviceAdmin" msgid="569715419543907930">"Επιτρέπει στον κάτοχο την αποστολή στόχων σε έναν διαχειριστή συσκευής. Δεν είναι απαραίτητο για συνήθεις εφαρμογές."</string>
<string name="permlab_bindTvInput" msgid="5601264742478168987">"σύνδεση σε μία είσοδο τηλεόρασης"</string>
@@ -742,6 +742,8 @@
<string name="permdesc_bindNotificationListenerService" msgid="985697918576902986">"Επιτρέπει στον κάτοχο τη δέσμευση στη διεπαφή ανωτάτου επιπέδου μιας υπηρεσίας ακρόασης ειδοποιήσεων. Δεν απαιτείται σε κανονικές εφαρμογές."</string>
<string name="permlab_bindConditionProviderService" msgid="1180107672332704641">"σύνδεση σε μια υπηρεσία παρόχου συνθηκών"</string>
<string name="permdesc_bindConditionProviderService" msgid="1680513931165058425">"Επιτρέπει στον κάτοχο τη σύνδεση στη διεπαφή ανωτάτου επιπέδου ενός παρόχου συνθηκών. Δεν απαιτείται για κανονικές εφαρμογές."</string>
+ <string name="permlab_bindMediaRouteService" msgid="6637740382272686835">"σύνδεση σε μια υπηρεσία δρομολόγησης μέσων"</string>
+ <string name="permdesc_bindMediaRouteService" msgid="6436655024972496687">"Επιτρέπει στον κάτοχο τη σύνδεση στη διεπαφή ανωτάτου επιπέδου μιας υπηρεσίας δρομολόγησης μέσων. Δεν απαιτείται για κανονικές εφαρμογές."</string>
<string name="permlab_bindDreamService" msgid="4153646965978563462">"δέσμευση σε υπηρεσία dream"</string>
<string name="permdesc_bindDreamService" msgid="7325825272223347863">"Επιτρέπει στον κάτοχο τη δέσμευση στη διεπαφή ανωτάτου επιπέδου μιας υπηρεσίας dream. Δεν απαιτείται σε κανονικές εφαρμογές."</string>
<string name="permlab_invokeCarrierSetup" msgid="3699600833975117478">"κλήση της εφαρμογής διαμόρφωσης που παρέχεται από την εταιρεία κινητής τηλεφωνίας"</string>
@@ -1283,6 +1285,9 @@
<skip />
<string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"Δεν είναι δυνατή η σύνδεση στο Wi-Fi"</string>
<string name="wifi_watchdog_network_disabled_detailed" msgid="5548780776418332675">" έχει κακή σύνδεση στο Διαδίκτυο."</string>
+ <string name="wifi_connect_alert_title" msgid="8455846016001810172">"Να επιτρέπεται η σύνδεση;"</string>
+ <string name="wifi_connect_alert_message" msgid="8930084523889618078">"%1$s θα ήθελε να συνδεθεί με %2$s"</string>
+ <string name="wifi_connect_default_application" msgid="7143109390475484319">"Μια εφαρμογή"</string>
<string name="wifi_p2p_dialog_title" msgid="97611782659324517">"Wi-Fi Direct"</string>
<string name="wifi_p2p_turnon_message" msgid="2909250942299627244">"Ξεκινήστε τη λειτουργία Wi-Fi Direct. Θα απενεργοποιηθεί η λειτουργία πελάτη/φορητού σημείου πρόσβασης Wi-Fi."</string>
<string name="wifi_p2p_failed_message" msgid="3763669677935623084">"Δεν ήταν δυνατή η εκκίνηση του Wi-Fi Direct."</string>
@@ -1776,8 +1781,7 @@
<string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Να γίνεται ερώτηση για τον κωδικό πρόσβασης, πριν από το ξεκαρφίτσωμα"</string>
<string name="battery_saver_description" msgid="2510530476513605742">"Για τη βελτίωση της διάρκειας ζωής της μπαταρίας, η λειτουργία εξοικονόμησης μπαταρίας μειώνει την απόδοση της συσκευής σας και περιορίζει τη δόνηση και την πλειονότητα των δεδομένων παρασκηνίου. Το ηλεκτρονικό ταχυδρομείου, η ανταλλαγή μηνυμάτων και άλλες εφαρμογές που βασίζονται στο συγχρονισμό ενδέχεται να μην ενημερώνονται, παρά μόνο εάν τις ανοίξετε.\n\nΗ λειτουργία εξοικονόμησης μπαταρίας απενεργοποιείται αυτόματα κατά τη φόρτιση της συσκευής σας."</string>
<string name="downtime_condition_summary" msgid="8761776337475705749">"Έως τη λήξη του νεκρού χρόνου σας στις <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
- <!-- no translation found for downtime_condition_line_one (8762708714645352010) -->
- <skip />
+ <string name="downtime_condition_line_one" msgid="8762708714645352010">"Έως τη λήξη του νεκρού χρόνου σας"</string>
<plurals name="zen_mode_duration_minutes_summary">
<item quantity="one" msgid="3177683545388923234">"Για ένα λεπτό (έως τις <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
<item quantity="other" msgid="2787867221129368935">"Για %1$d λεπτά (έως τις <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
@@ -1797,8 +1801,6 @@
<string name="zen_mode_until" msgid="7336308492289875088">"Έως τις <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
<string name="zen_mode_forever" msgid="4316804956488785559">"Επ\' αόριστον"</string>
<string name="toolbar_collapse_description" msgid="2821479483960330739">"Σύμπτυξη"</string>
- <!-- no translation found for zen_mode_next_alarm_summary (5915140424683747372) -->
- <skip />
- <!-- no translation found for zen_mode_next_alarm_line_one (5537042951553420916) -->
- <skip />
+ <string name="zen_mode_next_alarm_summary" msgid="5915140424683747372">"Έως την επόμενη ειδοποίηση στις <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
+ <string name="zen_mode_next_alarm_line_one" msgid="5537042951553420916">"Έως την επόμενη ειδοποίηση"</string>
</resources>
diff --git a/core/res/res/values-en-rGB/strings.xml b/core/res/res/values-en-rGB/strings.xml
index d5fcbe2..b986723 100644
--- a/core/res/res/values-en-rGB/strings.xml
+++ b/core/res/res/values-en-rGB/strings.xml
@@ -41,8 +41,6 @@
<string name="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g> secs"</string>
<string name="durationSecond" msgid="985669622276420331">"<xliff:g id="SECONDS">%1$d</xliff:g> sec"</string>
<string name="untitled" msgid="4638956954852782576">"<Untitled>"</string>
- <string name="ellipsis" msgid="7899829516048813237">"…"</string>
- <string name="ellipsis_two_dots" msgid="1228078994866030736">"‥"</string>
<string name="emptyPhoneNumber" msgid="7694063042079676517">"(No phone number)"</string>
<string name="unknownName" msgid="2277556546742746522">"(Unknown)"</string>
<string name="defaultVoiceMailAlphaTag" msgid="2660020990097733077">"Voicemail"</string>
@@ -415,6 +413,8 @@
<string name="permdesc_bindRemoteDisplay" msgid="1261242718727295981">"Allows the holder to bind to the top-level interface of a remote display. Should never be needed for normal apps."</string>
<string name="permlab_bindRemoteViews" msgid="5697987759897367099">"bind to a widget service"</string>
<string name="permdesc_bindRemoteViews" msgid="4717987810137692572">"Allows the holder to bind to the top-level interface of a widget service. Should never be needed for normal apps."</string>
+ <string name="permlab_bindRouteProvider" msgid="4869394607915096847">"bind to a route provider service"</string>
+ <string name="permdesc_bindRouteProvider" msgid="4703804520859960329">"Allows the holder to bind to any registered route providers. Should never be needed for normal apps."</string>
<string name="permlab_bindDeviceAdmin" msgid="8704986163711455010">"interact with device admin"</string>
<string name="permdesc_bindDeviceAdmin" msgid="569715419543907930">"Allows the holder to send intents to a device administrator. Should never be needed for normal apps."</string>
<string name="permlab_bindTvInput" msgid="5601264742478168987">"bind to a TV input"</string>
@@ -742,6 +742,8 @@
<string name="permdesc_bindNotificationListenerService" msgid="985697918576902986">"Allows the holder to bind to the top-level interface of a notification listener service. Should never be needed for normal apps."</string>
<string name="permlab_bindConditionProviderService" msgid="1180107672332704641">"bind to a condition provider service"</string>
<string name="permdesc_bindConditionProviderService" msgid="1680513931165058425">"Allows the holder to bind to the top-level interface of a condition provider service. Should never be needed for normal apps."</string>
+ <string name="permlab_bindMediaRouteService" msgid="6637740382272686835">"bind to a media route service"</string>
+ <string name="permdesc_bindMediaRouteService" msgid="6436655024972496687">"Allows the holder to bind to the top-level interface of a media route service. Should never be needed for normal apps."</string>
<string name="permlab_bindDreamService" msgid="4153646965978563462">"bind to a dream service"</string>
<string name="permdesc_bindDreamService" msgid="7325825272223347863">"Allows the holder to bind to the top-level interface of a dream service. Should never be needed for normal apps."</string>
<string name="permlab_invokeCarrierSetup" msgid="3699600833975117478">"invoke the carrier-provided configuration app"</string>
@@ -1283,6 +1285,9 @@
<skip />
<string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"Couldn\'t connect to Wi-Fi"</string>
<string name="wifi_watchdog_network_disabled_detailed" msgid="5548780776418332675">" has a poor Internet connection."</string>
+ <string name="wifi_connect_alert_title" msgid="8455846016001810172">"Allow connection?"</string>
+ <string name="wifi_connect_alert_message" msgid="8930084523889618078">"%1$s would like to connect to %2$s"</string>
+ <string name="wifi_connect_default_application" msgid="7143109390475484319">"An application"</string>
<string name="wifi_p2p_dialog_title" msgid="97611782659324517">"Wi-Fi Direct"</string>
<string name="wifi_p2p_turnon_message" msgid="2909250942299627244">"Start Wi-Fi Direct. This will turn off Wi-Fi client/hotspot."</string>
<string name="wifi_p2p_failed_message" msgid="3763669677935623084">"Couldn\'t start Wi-Fi Direct."</string>
diff --git a/core/res/res/values-en-rIN/strings.xml b/core/res/res/values-en-rIN/strings.xml
index d5fcbe2..b986723 100644
--- a/core/res/res/values-en-rIN/strings.xml
+++ b/core/res/res/values-en-rIN/strings.xml
@@ -41,8 +41,6 @@
<string name="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g> secs"</string>
<string name="durationSecond" msgid="985669622276420331">"<xliff:g id="SECONDS">%1$d</xliff:g> sec"</string>
<string name="untitled" msgid="4638956954852782576">"<Untitled>"</string>
- <string name="ellipsis" msgid="7899829516048813237">"…"</string>
- <string name="ellipsis_two_dots" msgid="1228078994866030736">"‥"</string>
<string name="emptyPhoneNumber" msgid="7694063042079676517">"(No phone number)"</string>
<string name="unknownName" msgid="2277556546742746522">"(Unknown)"</string>
<string name="defaultVoiceMailAlphaTag" msgid="2660020990097733077">"Voicemail"</string>
@@ -415,6 +413,8 @@
<string name="permdesc_bindRemoteDisplay" msgid="1261242718727295981">"Allows the holder to bind to the top-level interface of a remote display. Should never be needed for normal apps."</string>
<string name="permlab_bindRemoteViews" msgid="5697987759897367099">"bind to a widget service"</string>
<string name="permdesc_bindRemoteViews" msgid="4717987810137692572">"Allows the holder to bind to the top-level interface of a widget service. Should never be needed for normal apps."</string>
+ <string name="permlab_bindRouteProvider" msgid="4869394607915096847">"bind to a route provider service"</string>
+ <string name="permdesc_bindRouteProvider" msgid="4703804520859960329">"Allows the holder to bind to any registered route providers. Should never be needed for normal apps."</string>
<string name="permlab_bindDeviceAdmin" msgid="8704986163711455010">"interact with device admin"</string>
<string name="permdesc_bindDeviceAdmin" msgid="569715419543907930">"Allows the holder to send intents to a device administrator. Should never be needed for normal apps."</string>
<string name="permlab_bindTvInput" msgid="5601264742478168987">"bind to a TV input"</string>
@@ -742,6 +742,8 @@
<string name="permdesc_bindNotificationListenerService" msgid="985697918576902986">"Allows the holder to bind to the top-level interface of a notification listener service. Should never be needed for normal apps."</string>
<string name="permlab_bindConditionProviderService" msgid="1180107672332704641">"bind to a condition provider service"</string>
<string name="permdesc_bindConditionProviderService" msgid="1680513931165058425">"Allows the holder to bind to the top-level interface of a condition provider service. Should never be needed for normal apps."</string>
+ <string name="permlab_bindMediaRouteService" msgid="6637740382272686835">"bind to a media route service"</string>
+ <string name="permdesc_bindMediaRouteService" msgid="6436655024972496687">"Allows the holder to bind to the top-level interface of a media route service. Should never be needed for normal apps."</string>
<string name="permlab_bindDreamService" msgid="4153646965978563462">"bind to a dream service"</string>
<string name="permdesc_bindDreamService" msgid="7325825272223347863">"Allows the holder to bind to the top-level interface of a dream service. Should never be needed for normal apps."</string>
<string name="permlab_invokeCarrierSetup" msgid="3699600833975117478">"invoke the carrier-provided configuration app"</string>
@@ -1283,6 +1285,9 @@
<skip />
<string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"Couldn\'t connect to Wi-Fi"</string>
<string name="wifi_watchdog_network_disabled_detailed" msgid="5548780776418332675">" has a poor Internet connection."</string>
+ <string name="wifi_connect_alert_title" msgid="8455846016001810172">"Allow connection?"</string>
+ <string name="wifi_connect_alert_message" msgid="8930084523889618078">"%1$s would like to connect to %2$s"</string>
+ <string name="wifi_connect_default_application" msgid="7143109390475484319">"An application"</string>
<string name="wifi_p2p_dialog_title" msgid="97611782659324517">"Wi-Fi Direct"</string>
<string name="wifi_p2p_turnon_message" msgid="2909250942299627244">"Start Wi-Fi Direct. This will turn off Wi-Fi client/hotspot."</string>
<string name="wifi_p2p_failed_message" msgid="3763669677935623084">"Couldn\'t start Wi-Fi Direct."</string>
diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml
index e2764ad..73b3517 100644
--- a/core/res/res/values-es-rUS/strings.xml
+++ b/core/res/res/values-es-rUS/strings.xml
@@ -41,8 +41,6 @@
<string name="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g> s"</string>
<string name="durationSecond" msgid="985669622276420331">"<xliff:g id="SECONDS">%1$d</xliff:g> s"</string>
<string name="untitled" msgid="4638956954852782576">"<Sin título>"</string>
- <string name="ellipsis" msgid="7899829516048813237">"…"</string>
- <string name="ellipsis_two_dots" msgid="1228078994866030736">"‥"</string>
<string name="emptyPhoneNumber" msgid="7694063042079676517">"(No hay número de teléfono)"</string>
<string name="unknownName" msgid="2277556546742746522">"(Desconocida)"</string>
<string name="defaultVoiceMailAlphaTag" msgid="2660020990097733077">"Correo de voz"</string>
@@ -415,6 +413,8 @@
<string name="permdesc_bindRemoteDisplay" msgid="1261242718727295981">"Permite al propietario vincularse a la interfaz de nivel superior de una pantalla remota. Las aplicaciones normales no deberían necesitar este permiso."</string>
<string name="permlab_bindRemoteViews" msgid="5697987759897367099">"vincular a un servicio de widget"</string>
<string name="permdesc_bindRemoteViews" msgid="4717987810137692572">"Permite al propietario vincularse a la interfaz de nivel superior del servicio de widget. Las aplicaciones normales no deberían necesitar este permiso."</string>
+ <string name="permlab_bindRouteProvider" msgid="4869394607915096847">"vincular con un servicio de proveedor de rutas"</string>
+ <string name="permdesc_bindRouteProvider" msgid="4703804520859960329">"Permite al propietario vincular con proveedores de rutas registrados. No debe ser necesario para las aplicaciones normales."</string>
<string name="permlab_bindDeviceAdmin" msgid="8704986163711455010">"interactuar con un administrador de dispositivos"</string>
<string name="permdesc_bindDeviceAdmin" msgid="569715419543907930">"Permite enviar intentos a un administrador de dispositivos. Las aplicaciones normales no deberían necesitar este permiso."</string>
<string name="permlab_bindTvInput" msgid="5601264742478168987">"vincular a una entrada de TV"</string>
@@ -742,6 +742,8 @@
<string name="permdesc_bindNotificationListenerService" msgid="985697918576902986">"Permite al propietario vincularse a la interfaz de nivel superior de un servicio de agente de escucha de notificaciones. Las aplicaciones normales no deberían necesitar este permiso."</string>
<string name="permlab_bindConditionProviderService" msgid="1180107672332704641">"vincular con un servicio de proveedor de condiciones"</string>
<string name="permdesc_bindConditionProviderService" msgid="1680513931165058425">"Permite vincular con la interfaz de nivel superior de un servicio de proveedor de condiciones. Las aplicaciones normales no deberían necesitar este permiso."</string>
+ <string name="permlab_bindMediaRouteService" msgid="6637740382272686835">"vincular a un servicio de enrutamiento de contenido multimedia"</string>
+ <string name="permdesc_bindMediaRouteService" msgid="6436655024972496687">"Permite vincular con la interfaz de nivel superior de un servicio de enrutamiento de contenido multimedia. Las aplicaciones normales no deberían necesitar este permiso."</string>
<string name="permlab_bindDreamService" msgid="4153646965978563462">"vincularse a un servicio de protector de pantalla interactivo"</string>
<string name="permdesc_bindDreamService" msgid="7325825272223347863">"Permite al propietario vincularse a la interfaz de nivel superior de un servicio de protector de pantalla interactivo. Las aplicaciones normales no deberían necesitar este permiso."</string>
<string name="permlab_invokeCarrierSetup" msgid="3699600833975117478">"ejecutar la aplicación de configuración proporcionada por el proveedor"</string>
@@ -1283,6 +1285,9 @@
<skip />
<string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"No se pudo conectar a la red Wi-Fi."</string>
<string name="wifi_watchdog_network_disabled_detailed" msgid="5548780776418332675">" tiene una mala conexión a Internet."</string>
+ <string name="wifi_connect_alert_title" msgid="8455846016001810172">"¿Permitir la conexión?"</string>
+ <string name="wifi_connect_alert_message" msgid="8930084523889618078">"%1$s quiere conectarse a %2$s."</string>
+ <string name="wifi_connect_default_application" msgid="7143109390475484319">"Una aplicación"</string>
<string name="wifi_p2p_dialog_title" msgid="97611782659324517">"Wi-Fi Direct"</string>
<string name="wifi_p2p_turnon_message" msgid="2909250942299627244">"Iniciar Wi-Fi Direct. Se desactivará el funcionamiento de la zona o del cliente Wi-Fi."</string>
<string name="wifi_p2p_failed_message" msgid="3763669677935623084">"No se pudo iniciar Wi-Fi Direct."</string>
diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml
index 4c72e3d..df9bccf 100644
--- a/core/res/res/values-es/strings.xml
+++ b/core/res/res/values-es/strings.xml
@@ -41,8 +41,6 @@
<string name="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g> s"</string>
<string name="durationSecond" msgid="985669622276420331">"<xliff:g id="SECONDS">%1$d</xliff:g> s"</string>
<string name="untitled" msgid="4638956954852782576">"<Sin título>"</string>
- <string name="ellipsis" msgid="7899829516048813237">"…"</string>
- <string name="ellipsis_two_dots" msgid="1228078994866030736">"..."</string>
<string name="emptyPhoneNumber" msgid="7694063042079676517">"(Sin número de teléfono)"</string>
<string name="unknownName" msgid="2277556546742746522">"Desconocido"</string>
<string name="defaultVoiceMailAlphaTag" msgid="2660020990097733077">"Buzón de voz"</string>
@@ -415,6 +413,8 @@
<string name="permdesc_bindRemoteDisplay" msgid="1261242718727295981">"Permite enlazar con la interfaz de nivel superior de una pantalla remota. Las aplicaciones normales no deberían necesitar este permiso."</string>
<string name="permlab_bindRemoteViews" msgid="5697987759897367099">"enlazar con un servicio de widget"</string>
<string name="permdesc_bindRemoteViews" msgid="4717987810137692572">"Permite enlazar con la interfaz de nivel superior de un servicio de widget. Las aplicaciones normales no deberían necesitar este permiso."</string>
+ <string name="permlab_bindRouteProvider" msgid="4869394607915096847">"enlazar con un servicio de proveedor de rutas"</string>
+ <string name="permdesc_bindRouteProvider" msgid="4703804520859960329">"Permite enlazar con proveedores de rutas registrados. No debe ser necesario para las aplicaciones normales."</string>
<string name="permlab_bindDeviceAdmin" msgid="8704986163711455010">"interactuar con el administrador de un dispositivo"</string>
<string name="permdesc_bindDeviceAdmin" msgid="569715419543907930">"Permite que se envíen intentos a un administrador de dispositivos. Las aplicaciones normales nunca deberían necesitar este permiso."</string>
<string name="permlab_bindTvInput" msgid="5601264742478168987">"enlazar a una entrada de TV"</string>
@@ -742,6 +742,8 @@
<string name="permdesc_bindNotificationListenerService" msgid="985697918576902986">"Permite enlazar con la interfaz de nivel superior de un servicio de detector de notificaciones. No debe ser necesario para las aplicaciones normales."</string>
<string name="permlab_bindConditionProviderService" msgid="1180107672332704641">"enlazar con un servicio de proveedor de condiciones"</string>
<string name="permdesc_bindConditionProviderService" msgid="1680513931165058425">"Permite enlazar con la interfaz de nivel superior de un servicio de proveedor de condiciones. Las aplicaciones normales no deberían necesitar este permiso."</string>
+ <string name="permlab_bindMediaRouteService" msgid="6637740382272686835">"enlazar a un servicio de rutas multimedia"</string>
+ <string name="permdesc_bindMediaRouteService" msgid="6436655024972496687">"Permite enlazar con la interfaz de nivel superior de un servicio de rutas multimedia. No debe ser necesario para las aplicaciones normales."</string>
<string name="permlab_bindDreamService" msgid="4153646965978563462">"enlazar con un servicio de salvapantallas"</string>
<string name="permdesc_bindDreamService" msgid="7325825272223347863">"Permite enlazar con la interfaz de nivel superior de un servicio de salvapantallas. Las aplicaciones normales no deberían necesitar este permiso."</string>
<string name="permlab_invokeCarrierSetup" msgid="3699600833975117478">"ejecutar la aplicación de configuración proporcionada por el operador"</string>
@@ -1283,6 +1285,9 @@
<skip />
<string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"No se ha podido establecer conexión con la red Wi-Fi."</string>
<string name="wifi_watchdog_network_disabled_detailed" msgid="5548780776418332675">" tiene una conexión inestable a Internet."</string>
+ <string name="wifi_connect_alert_title" msgid="8455846016001810172">"¿Permitir la conexión?"</string>
+ <string name="wifi_connect_alert_message" msgid="8930084523889618078">"%1$s quiere conectarse a %2$s"</string>
+ <string name="wifi_connect_default_application" msgid="7143109390475484319">"Una aplicación"</string>
<string name="wifi_p2p_dialog_title" msgid="97611782659324517">"Wi-Fi Direct"</string>
<string name="wifi_p2p_turnon_message" msgid="2909250942299627244">"Iniciar Wi-Fi Direct. Se desactivará el funcionamiento de la zona o del cliente Wi-Fi."</string>
<string name="wifi_p2p_failed_message" msgid="3763669677935623084">"No se ha podido iniciar Wi-Fi Direct."</string>
@@ -1776,8 +1781,7 @@
<string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Solicitar contraseña para desactivar"</string>
<string name="battery_saver_description" msgid="2510530476513605742">"Para ayudar a mejorar la duración de la batería, la función de ahorro de energía reduce el rendimiento del dispositivo y limita la vibración y la mayor parte de la transmisión de datos en segundo plano. Es posible que las aplicaciones que se sincronizan, como las de correo y envío de mensajes, no se actualicen a menos que las abras.\n\nLa función de ahorro de energía se desactiva automáticamente cuando el dispositivo se carga."</string>
<string name="downtime_condition_summary" msgid="8761776337475705749">"Hasta que el tiempo de inactividad finalice el <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
- <!-- no translation found for downtime_condition_line_one (8762708714645352010) -->
- <skip />
+ <string name="downtime_condition_line_one" msgid="8762708714645352010">"Hasta que finalice el tiempo de inactividad"</string>
<plurals name="zen_mode_duration_minutes_summary">
<item quantity="one" msgid="3177683545388923234">"Durante un minuto (hasta las <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
<item quantity="other" msgid="2787867221129368935">"Durante %1$d minutos (hasta las <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
@@ -1797,8 +1801,6 @@
<string name="zen_mode_until" msgid="7336308492289875088">"Hasta las <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
<string name="zen_mode_forever" msgid="4316804956488785559">"Indefinidamente"</string>
<string name="toolbar_collapse_description" msgid="2821479483960330739">"Contraer"</string>
- <!-- no translation found for zen_mode_next_alarm_summary (5915140424683747372) -->
- <skip />
- <!-- no translation found for zen_mode_next_alarm_line_one (5537042951553420916) -->
- <skip />
+ <string name="zen_mode_next_alarm_summary" msgid="5915140424683747372">"Hasta la próxima alarma a las <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
+ <string name="zen_mode_next_alarm_line_one" msgid="5537042951553420916">"Hasta la próxima alarma"</string>
</resources>
diff --git a/core/res/res/values-et-rEE/strings.xml b/core/res/res/values-et-rEE/strings.xml
index 7bc7324..a02208f 100644
--- a/core/res/res/values-et-rEE/strings.xml
+++ b/core/res/res/values-et-rEE/strings.xml
@@ -41,8 +41,6 @@
<string name="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g> s"</string>
<string name="durationSecond" msgid="985669622276420331">"<xliff:g id="SECONDS">%1$d</xliff:g> s"</string>
<string name="untitled" msgid="4638956954852782576">"<Pealkirjata>"</string>
- <string name="ellipsis" msgid="7899829516048813237">"…"</string>
- <string name="ellipsis_two_dots" msgid="1228078994866030736">"‥."</string>
<string name="emptyPhoneNumber" msgid="7694063042079676517">"(Telefoninumbrit pole)"</string>
<string name="unknownName" msgid="2277556546742746522">"(Tundmatu)"</string>
<string name="defaultVoiceMailAlphaTag" msgid="2660020990097733077">"Kõnepost"</string>
@@ -415,6 +413,8 @@
<string name="permdesc_bindRemoteDisplay" msgid="1261242718727295981">"Lubab omanikul siduda rakenduse kaugekraani ülataseme liidesega. Tavarakenduste puhul ei peaks seda kunagi vaja minema."</string>
<string name="permlab_bindRemoteViews" msgid="5697987759897367099">"vidinateenusega sidumine"</string>
<string name="permdesc_bindRemoteViews" msgid="4717987810137692572">"Lubab omanikul siduda vidina teenuse ülataseme liidesega. Tavarakenduste puhul ei peaks seda kunagi vaja minema."</string>
+ <string name="permlab_bindRouteProvider" msgid="4869394607915096847">"sidumine marsruudi pakkumisteenusega"</string>
+ <string name="permdesc_bindRouteProvider" msgid="4703804520859960329">"Lubab õiguste omajal luua seosed kõikide registreeritud marsruutide pakkujatega. Pole kunagi vajalik tavaliste rakenduste korral."</string>
<string name="permlab_bindDeviceAdmin" msgid="8704986163711455010">"seadme administraatoriga suhtlemine"</string>
<string name="permdesc_bindDeviceAdmin" msgid="569715419543907930">"Võimaldab omanikul saata kavatsusi seadme administraatorile. Tavarakenduste puhul ei peaks seda kunagi vaja minema."</string>
<string name="permlab_bindTvInput" msgid="5601264742478168987">"sidumine TV-sisendiga"</string>
@@ -742,6 +742,8 @@
<string name="permdesc_bindNotificationListenerService" msgid="985697918576902986">"Võimaldab omanikul siduda märguannete kuulamisteenuse ülemise taseme kasutajaliidese. Seda ei tohiks tavarakenduste puhul kunagi vaja olla."</string>
<string name="permlab_bindConditionProviderService" msgid="1180107672332704641">"seo tingimuse pakkuja teenusega"</string>
<string name="permdesc_bindConditionProviderService" msgid="1680513931165058425">"Lubab omanikul siduda tingimuse pakkuja teenuse ülataseme liidesega. Pole kunagi vajalik tavaliste rakenduste puhul."</string>
+ <string name="permlab_bindMediaRouteService" msgid="6637740382272686835">"meediumi marsruutimise teenusega sidumine"</string>
+ <string name="permdesc_bindMediaRouteService" msgid="6436655024972496687">"Lubab omanikul siduda meediumi marsruutimise teenuse ülataseme liidesega. Pole kunagi vajalik tavaliste rakenduste puhul."</string>
<string name="permlab_bindDreamService" msgid="4153646965978563462">"sidumine uneteenusega"</string>
<string name="permdesc_bindDreamService" msgid="7325825272223347863">"Lubab omanikul siduda uneteenuse ülataseme liidesega. Tavarakenduste puhul ei peaks seda kunagi vaja minema."</string>
<string name="permlab_invokeCarrierSetup" msgid="3699600833975117478">"operaatoripoolse konfiguratsioonirakenduse aktiveerimine"</string>
@@ -1283,6 +1285,9 @@
<skip />
<string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"Ei saanud WiFi-ga ühendust"</string>
<string name="wifi_watchdog_network_disabled_detailed" msgid="5548780776418332675">" on halb Interneti-ühendus."</string>
+ <string name="wifi_connect_alert_title" msgid="8455846016001810172">"Kas lubada ühendus?"</string>
+ <string name="wifi_connect_alert_message" msgid="8930084523889618078">"%1$s soovib luua ühenduse võrguga %2$s"</string>
+ <string name="wifi_connect_default_application" msgid="7143109390475484319">"Rakendus"</string>
<string name="wifi_p2p_dialog_title" msgid="97611782659324517">"WiFi Direct"</string>
<string name="wifi_p2p_turnon_message" msgid="2909250942299627244">"Käivitage WiFi otseühendus. See lülitab välja WiFi kliendi/leviala."</string>
<string name="wifi_p2p_failed_message" msgid="3763669677935623084">"WiFi otseühenduse käivitamine ebaõnnestus."</string>
@@ -1776,8 +1781,7 @@
<string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Enne vabastamist küsi parooli"</string>
<string name="battery_saver_description" msgid="2510530476513605742">"Aku kestuse parandamiseks vähendab akusäästja teie seadme jõudlust ja piirab vibratsiooni ning suuremat osa taustaandmetest. E-posti, sõnumsidet ja muid sünkroonimisele tuginevaid rakendusi võidakse värskendada ainult siis, kui te need avate.\n\nAkusäästja lülitatakse seadme laadimise ajal automaatselt välja."</string>
<string name="downtime_condition_summary" msgid="8761776337475705749">"Kuni seisakuaja lõppemiseni kell <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
- <!-- no translation found for downtime_condition_line_one (8762708714645352010) -->
- <skip />
+ <string name="downtime_condition_line_one" msgid="8762708714645352010">"Kuni puhkeaja lõpuni"</string>
<plurals name="zen_mode_duration_minutes_summary">
<item quantity="one" msgid="3177683545388923234">"Üheks minutiks (kuni <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
<item quantity="other" msgid="2787867221129368935">"%1$d minutiks (kuni <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
@@ -1797,8 +1801,6 @@
<string name="zen_mode_until" msgid="7336308492289875088">"Kuni <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
<string name="zen_mode_forever" msgid="4316804956488785559">"Määramata ajaks"</string>
<string name="toolbar_collapse_description" msgid="2821479483960330739">"Ahendamine"</string>
- <!-- no translation found for zen_mode_next_alarm_summary (5915140424683747372) -->
- <skip />
- <!-- no translation found for zen_mode_next_alarm_line_one (5537042951553420916) -->
- <skip />
+ <string name="zen_mode_next_alarm_summary" msgid="5915140424683747372">"Kuni järgmise alarmini <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
+ <string name="zen_mode_next_alarm_line_one" msgid="5537042951553420916">"Kuni järgmise alarmini"</string>
</resources>
diff --git a/core/res/res/values-eu-rES/strings.xml b/core/res/res/values-eu-rES/strings.xml
index c98f5b1..847a0f1 100644
--- a/core/res/res/values-eu-rES/strings.xml
+++ b/core/res/res/values-eu-rES/strings.xml
@@ -41,8 +41,6 @@
<string name="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g> s"</string>
<string name="durationSecond" msgid="985669622276420331">"<xliff:g id="SECONDS">%1$d</xliff:g> s"</string>
<string name="untitled" msgid="4638956954852782576">"<Izengabea>"</string>
- <string name="ellipsis" msgid="7899829516048813237">"…"</string>
- <string name="ellipsis_two_dots" msgid="1228078994866030736">"‥"</string>
<string name="emptyPhoneNumber" msgid="7694063042079676517">"(Ez dago telefono-zenbakirik)"</string>
<string name="unknownName" msgid="2277556546742746522">"(Ezezaguna)"</string>
<string name="defaultVoiceMailAlphaTag" msgid="2660020990097733077">"Erantzungailua"</string>
@@ -415,6 +413,8 @@
<string name="permdesc_bindRemoteDisplay" msgid="1261242718727295981">"Urruneko pantaila baten goi-mailako interfazera lotzeko aukera ematen dio titularrari. Aplikazio normalek ez dute baimen hau behar."</string>
<string name="permlab_bindRemoteViews" msgid="5697987759897367099">"lotu widget-zerbitzu batekin"</string>
<string name="permdesc_bindRemoteViews" msgid="4717987810137692572">"Widget-zerbitzu baten goi-mailako interfazeari lotzea baimentzen die titularrei. Aplikazio normalek ez lukete beharko."</string>
+ <string name="permlab_bindRouteProvider" msgid="4869394607915096847">"Lotu ibilbide-hornitzaileen zerbitzuei"</string>
+ <string name="permdesc_bindRouteProvider" msgid="4703804520859960329">"Erregistratutako ibilbide-hornitzaileei lotzea baimentzen die titularrei. Aplikazio normalek ez lukete beharko."</string>
<string name="permlab_bindDeviceAdmin" msgid="8704986163711455010">"aritu elkarlanean gailu baten administratzailearekin"</string>
<string name="permdesc_bindDeviceAdmin" msgid="569715419543907930">"Gailu-administratzaileei xedeak bidaltzea baimentzen die titularrei. Aplikazio normalek ez lukete beharko."</string>
<string name="permlab_bindTvInput" msgid="5601264742478168987">"Lotu telebista-sarrerei"</string>
@@ -742,6 +742,8 @@
<string name="permdesc_bindNotificationListenerService" msgid="985697918576902986">"Jakinarazpenak hautemateko zerbitzu baten goi-mailako interfazera lotzeko aukera ematen dio titularrari. Aplikazio normalek ez dute baimen hau behar."</string>
<string name="permlab_bindConditionProviderService" msgid="1180107672332704641">"Lotu baldintza-hornitzaileen zerbitzuei"</string>
<string name="permdesc_bindConditionProviderService" msgid="1680513931165058425">"Baldintza-hornitzaileen zerbitzuen goi-mailako interfazeari lotzea baimentzen die titularrei. Aplikazio normalek ez lukete beharko."</string>
+ <string name="permlab_bindMediaRouteService" msgid="6637740382272686835">"lotetsi multimedia-irteerako zerbitzu bati"</string>
+ <string name="permdesc_bindMediaRouteService" msgid="6436655024972496687">"Multimedia-irteerako zerbitzu baten goi-mailako interfazeari lotzea baimentzen die titularrei. Aplikazio normalek ez lukete beharko."</string>
<string name="permlab_bindDreamService" msgid="4153646965978563462">"lotu dream zerbitzuei"</string>
<string name="permdesc_bindDreamService" msgid="7325825272223347863">"Dream zerbitzu baten goi-mailako interfazeari lotzea baimentzen die titularrei. Aplikazio normalek ez lukete beharko."</string>
<string name="permlab_invokeCarrierSetup" msgid="3699600833975117478">"Deitu operadorearen konfigurazio-aplikazioari"</string>
@@ -1283,6 +1285,9 @@
<skip />
<string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"Ezin izan da Wi-Fi sarera konektatu"</string>
<string name="wifi_watchdog_network_disabled_detailed" msgid="5548780776418332675">" Interneteko konexio txarra du."</string>
+ <string name="wifi_connect_alert_title" msgid="8455846016001810172">"Konektatzea baimendu nahi diozu?"</string>
+ <string name="wifi_connect_alert_message" msgid="8930084523889618078">"%1$s aplikazioak %2$s sarera konektatu nahi du"</string>
+ <string name="wifi_connect_default_application" msgid="7143109390475484319">"Aplikazio bat"</string>
<string name="wifi_p2p_dialog_title" msgid="97611782659324517">"Wi-Fi Direct"</string>
<string name="wifi_p2p_turnon_message" msgid="2909250942299627244">"Hasi Wi-Fi Direct. Wi-Fi bezeroa edo sare publikoa desaktibatuko da."</string>
<string name="wifi_p2p_failed_message" msgid="3763669677935623084">"Ezin izan da Wi-Fi Direct hasi."</string>
diff --git a/core/res/res/values-fa/strings.xml b/core/res/res/values-fa/strings.xml
index cf3d2be..fb288aa 100644
--- a/core/res/res/values-fa/strings.xml
+++ b/core/res/res/values-fa/strings.xml
@@ -41,8 +41,6 @@
<string name="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g> ثانیه"</string>
<string name="durationSecond" msgid="985669622276420331">"<xliff:g id="SECONDS">%1$d</xliff:g> ثانیه"</string>
<string name="untitled" msgid="4638956954852782576">"<بدون عنوان>"</string>
- <string name="ellipsis" msgid="7899829516048813237">"…"</string>
- <string name="ellipsis_two_dots" msgid="1228078994866030736">".."</string>
<string name="emptyPhoneNumber" msgid="7694063042079676517">"(بدون شماره تلفن)"</string>
<string name="unknownName" msgid="2277556546742746522">"(ناشناس)"</string>
<string name="defaultVoiceMailAlphaTag" msgid="2660020990097733077">"پست صوتی"</string>
@@ -415,6 +413,8 @@
<string name="permdesc_bindRemoteDisplay" msgid="1261242718727295981">"به دارنده امکان میدهد تا به رابط سطح بالای نمایشگر راه دور وصل شود. نباید هرگز برای برنامههای عادی لازم باشد."</string>
<string name="permlab_bindRemoteViews" msgid="5697987759897367099">"اتصال به یک سرویس ابزارک"</string>
<string name="permdesc_bindRemoteViews" msgid="4717987810137692572">"به دارنده اجازه میدهد که به رابط سطح بالای سرویس ابزارک متصل شود. هرگز برای برنامههای معمولی مورد نیاز نیست."</string>
+ <string name="permlab_bindRouteProvider" msgid="4869394607915096847">"اتصال به یک سرویس ارائهدهنده مسیر"</string>
+ <string name="permdesc_bindRouteProvider" msgid="4703804520859960329">"به دارنده امکان میدهد به هر ارائهدهنده مسیر ثبت شدهای متصل شود. هرگز برای برنامههای عادی مورد نیاز نیست."</string>
<string name="permlab_bindDeviceAdmin" msgid="8704986163711455010">"تعامل با یک سرپرست دستگاه"</string>
<string name="permdesc_bindDeviceAdmin" msgid="569715419543907930">"به دارنده اجازه میدهد اهداف خود را به سرپرست دستگاه ارسال کند. برنامههای معمولی هیچگاه به این ویژگی نیازی ندارند."</string>
<string name="permlab_bindTvInput" msgid="5601264742478168987">"اتصال به ورودی تلویزیون"</string>
@@ -742,6 +742,8 @@
<string name="permdesc_bindNotificationListenerService" msgid="985697918576902986">"به دارنده اجازه میدهد به یک رابط سطح بالای سرویس شنونده اعلان متصل شود. هرگز نباید برای برنامههای عادی لازم شود."</string>
<string name="permlab_bindConditionProviderService" msgid="1180107672332704641">"مقید بودن به سرویس ارائهدهنده وضعیت"</string>
<string name="permdesc_bindConditionProviderService" msgid="1680513931165058425">"به دارنده امکان میدهد تا به واسط سطح بالای سرویس ارائهدهنده وضعیت مقید باشد. برای برنامههای عادی هرگز نباید لازم باشد."</string>
+ <string name="permlab_bindMediaRouteService" msgid="6637740382272686835">"اتصال به یک سرویس مسیر رسانهای"</string>
+ <string name="permdesc_bindMediaRouteService" msgid="6436655024972496687">"به دارنده امکان میدهد به واسط کاربر سطح بالای سرویس مسیر رسانهای متصل شود. هرگز نباید برای برنامههای عادی لازم شود."</string>
<string name="permlab_bindDreamService" msgid="4153646965978563462">"اتصال به سرویس مورد نظر"</string>
<string name="permdesc_bindDreamService" msgid="7325825272223347863">"به برنامه اجازه میدهد که به رابط سطح بالای سرویس مورد نظر متصل شود. هرگز نباید برای برنامههای معمولی مورد نیاز باشد."</string>
<string name="permlab_invokeCarrierSetup" msgid="3699600833975117478">"لغو برنامه پیکربندی ارائه شده توسط شرکت مخابراتی"</string>
@@ -1283,6 +1285,9 @@
<skip />
<string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"اتصال به Wi-Fi ممکن نیست"</string>
<string name="wifi_watchdog_network_disabled_detailed" msgid="5548780776418332675">" اتصال اینترنتی ضعیفی دارد."</string>
+ <string name="wifi_connect_alert_title" msgid="8455846016001810172">"اتصال اجازه داده شود؟"</string>
+ <string name="wifi_connect_alert_message" msgid="8930084523889618078">"%1$s میخواهد به %2$s متصل شود"</string>
+ <string name="wifi_connect_default_application" msgid="7143109390475484319">"برنامه"</string>
<string name="wifi_p2p_dialog_title" msgid="97611782659324517">"Wi-Fi Direct"</string>
<string name="wifi_p2p_turnon_message" msgid="2909250942299627244">"Wi-Fi Direct را شروع کنید. این کار نقطه اتصال/سرویس گیرنده Wi-Fi را غیرفعال خواهد کرد."</string>
<string name="wifi_p2p_failed_message" msgid="3763669677935623084">"Wi-Fi Direct شروع نشد."</string>
@@ -1776,8 +1781,7 @@
<string name="lock_to_app_unlock_password" msgid="6380979775916974414">"درخواست گذرواژه قبل از برداشتن پین"</string>
<string name="battery_saver_description" msgid="2510530476513605742">"برای کمک به بهبود عمر باتری، ذخیرهکننده باتری عملکرد دستگاهتان را کاهش میدهد و اغلب اطلاعات پسزمینه و لرزش را محدود میکند. ایمیل، پیامرسانی و سایر برنامههایی که به همگامسازی وابسته هستند ممکن است بهروز نشوند مگر اینکه آنها را باز کنید.\n\nوقتی دستگاهتان شارژ میشود، ذخیرهکننده باتری به صورت خودکار خاموش میشود."</string>
<string name="downtime_condition_summary" msgid="8761776337475705749">"تا زمانی که زمان استراحت در <xliff:g id="FORMATTEDTIME">%1$s</xliff:g> به پایان برسد"</string>
- <!-- no translation found for downtime_condition_line_one (8762708714645352010) -->
- <skip />
+ <string name="downtime_condition_line_one" msgid="8762708714645352010">"تا زمان اتمام فرویش"</string>
<plurals name="zen_mode_duration_minutes_summary">
<item quantity="one" msgid="3177683545388923234">"به مدت یک دقیقه (تا <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
<item quantity="other" msgid="2787867221129368935">"به مدت %1$d دقیقه (تا <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
@@ -1797,8 +1801,6 @@
<string name="zen_mode_until" msgid="7336308492289875088">"تا <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
<string name="zen_mode_forever" msgid="4316804956488785559">"نامحدود"</string>
<string name="toolbar_collapse_description" msgid="2821479483960330739">"کوچک کردن"</string>
- <!-- no translation found for zen_mode_next_alarm_summary (5915140424683747372) -->
- <skip />
- <!-- no translation found for zen_mode_next_alarm_line_one (5537042951553420916) -->
- <skip />
+ <string name="zen_mode_next_alarm_summary" msgid="5915140424683747372">"تا هشدار بعدی در <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
+ <string name="zen_mode_next_alarm_line_one" msgid="5537042951553420916">"تا هشدار بعدی"</string>
</resources>
diff --git a/core/res/res/values-fi/strings.xml b/core/res/res/values-fi/strings.xml
index f41e947..5e73f0c 100644
--- a/core/res/res/values-fi/strings.xml
+++ b/core/res/res/values-fi/strings.xml
@@ -41,8 +41,6 @@
<string name="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g> s"</string>
<string name="durationSecond" msgid="985669622276420331">"<xliff:g id="SECONDS">%1$d</xliff:g> s"</string>
<string name="untitled" msgid="4638956954852782576">"<Nimetön>"</string>
- <string name="ellipsis" msgid="7899829516048813237">"…"</string>
- <string name="ellipsis_two_dots" msgid="1228078994866030736">".."</string>
<string name="emptyPhoneNumber" msgid="7694063042079676517">"(Ei puhelinnumeroa)"</string>
<string name="unknownName" msgid="2277556546742746522">"(Tuntematon)"</string>
<string name="defaultVoiceMailAlphaTag" msgid="2660020990097733077">"Vastaaja"</string>
@@ -415,6 +413,8 @@
<string name="permdesc_bindRemoteDisplay" msgid="1261242718727295981">"Antaa sovelluksen sitoutua etänäytön ylemmän tason käyttöliittymään. Ei tavallisten sovelluksien käyttöön."</string>
<string name="permlab_bindRemoteViews" msgid="5697987759897367099">"sitoudu widget-palveluun"</string>
<string name="permdesc_bindRemoteViews" msgid="4717987810137692572">"Antaa sovelluksen sitoutua widget-palvelun ylemmän tason käyttöliittymään. Ei tavallisten sovelluksien käyttöön."</string>
+ <string name="permlab_bindRouteProvider" msgid="4869394607915096847">"reitin tarjoajan palveluun sitominen"</string>
+ <string name="permdesc_bindRouteProvider" msgid="4703804520859960329">"Antaa sovelluksen luoda sidoksen mihin tahansa rekisteröityyn reitin tarjoajaan. Ei tavallisten sovelluksien käyttöön."</string>
<string name="permlab_bindDeviceAdmin" msgid="8704986163711455010">"kommunikoi laitteen järjestelmänvalvojan kanssa"</string>
<string name="permdesc_bindDeviceAdmin" msgid="569715419543907930">"Antaa sovelluksen lähettää aikomuksia laitteen järjestelmänvalvojalle. Ei tavallisten sovellusten käyttöön."</string>
<string name="permlab_bindTvInput" msgid="5601264742478168987">"sido TV-tuloon"</string>
@@ -742,6 +742,8 @@
<string name="permdesc_bindNotificationListenerService" msgid="985697918576902986">"Antaa sovelluksen sitoutua ilmoituskuuntelijan ylimmän tason käyttöliittymään. Ei tavallisten sovelluksien käyttöön."</string>
<string name="permlab_bindConditionProviderService" msgid="1180107672332704641">"ehtojen toimituspalveluun sitominen"</string>
<string name="permdesc_bindConditionProviderService" msgid="1680513931165058425">"Antaa sovelluksen luoda sidoksen ehtojen toimituspalvelun ylätason rajapintaan. Ei tavallisten sovelluksien käyttöön."</string>
+ <string name="permlab_bindMediaRouteService" msgid="6637740382272686835">"median reitityspalveluun sitoutuminen"</string>
+ <string name="permdesc_bindMediaRouteService" msgid="6436655024972496687">"Antaa sovelluksen sitoutua median reitityspalvelun ylätason liittymään. Ei tavallisten sovellusten käyttöön."</string>
<string name="permlab_bindDreamService" msgid="4153646965978563462">"sitoudu Unelma-palveluun"</string>
<string name="permdesc_bindDreamService" msgid="7325825272223347863">"Antaa sovelluksen sitoutua Unelma-palvelun ylemmän tason käyttöliittymään. Ei tavallisten sovelluksien käyttöön."</string>
<string name="permlab_invokeCarrierSetup" msgid="3699600833975117478">"Palveluntarjoajan määrityssovelluksen käynnistäminen"</string>
@@ -1283,6 +1285,9 @@
<skip />
<string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"Wi-Fi-yhteyden muodostaminen epäonnistui"</string>
<string name="wifi_watchdog_network_disabled_detailed" msgid="5548780776418332675">" : huono internetyhteys."</string>
+ <string name="wifi_connect_alert_title" msgid="8455846016001810172">"Sallitaanko yhteys?"</string>
+ <string name="wifi_connect_alert_message" msgid="8930084523889618078">"%1$s haluaa yhdistää kohteeseen %2$s"</string>
+ <string name="wifi_connect_default_application" msgid="7143109390475484319">"Sovellus"</string>
<string name="wifi_p2p_dialog_title" msgid="97611782659324517">"Suora wifi-yhteys"</string>
<string name="wifi_p2p_turnon_message" msgid="2909250942299627244">"Käynnistä suora wifi-yhteys. Wi-Fi-asiakas/-hotspot poistetaan käytöstä."</string>
<string name="wifi_p2p_failed_message" msgid="3763669677935623084">"Suoran wifi-yhteyden käynnistäminen epäonnistui."</string>
@@ -1776,8 +1781,7 @@
<string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Pyydä salasana ennen irrotusta"</string>
<string name="battery_saver_description" msgid="2510530476513605742">"Akunsäästötoiminto heikentää laitteen suorituskykyä ja rajoittaa värinää ja useimpia taustatietoja akun iän pidentämiseksi. Sähköposti, pikaviestit ja muut synkronointia edellyttävät sovellukset eivät ehkä päivity, ellet käynnistä niitä.\n\nAkunsäästö kytkeytyy automaattisesti pois laitteen akun latauksen ajaksi."</string>
<string name="downtime_condition_summary" msgid="8761776337475705749">"Käyttökatkos päättyy klo <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
- <!-- no translation found for downtime_condition_line_one (8762708714645352010) -->
- <skip />
+ <string name="downtime_condition_line_one" msgid="8762708714645352010">"Vapaa-aikasi päättymiseen saakka"</string>
<plurals name="zen_mode_duration_minutes_summary">
<item quantity="one" msgid="3177683545388923234">"Yksi minuutti (kunnes kello on <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
<item quantity="other" msgid="2787867221129368935">"%1$d minuuttia (kunnes kello on <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
@@ -1797,8 +1801,6 @@
<string name="zen_mode_until" msgid="7336308492289875088">"Kunnes kello on <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
<string name="zen_mode_forever" msgid="4316804956488785559">"Toistaiseksi"</string>
<string name="toolbar_collapse_description" msgid="2821479483960330739">"Kutista"</string>
- <!-- no translation found for zen_mode_next_alarm_summary (5915140424683747372) -->
- <skip />
- <!-- no translation found for zen_mode_next_alarm_line_one (5537042951553420916) -->
- <skip />
+ <string name="zen_mode_next_alarm_summary" msgid="5915140424683747372">"Seuraavaan herätykseen saakka (<xliff:g id="FORMATTEDTIME">%1$s</xliff:g>)"</string>
+ <string name="zen_mode_next_alarm_line_one" msgid="5537042951553420916">"Seuraavaan herätykseen saakka"</string>
</resources>
diff --git a/core/res/res/values-fr-rCA/strings.xml b/core/res/res/values-fr-rCA/strings.xml
index aa049f2..12f0027 100644
--- a/core/res/res/values-fr-rCA/strings.xml
+++ b/core/res/res/values-fr-rCA/strings.xml
@@ -41,8 +41,6 @@
<string name="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g> s"</string>
<string name="durationSecond" msgid="985669622276420331">"<xliff:g id="SECONDS">%1$d</xliff:g> s"</string>
<string name="untitled" msgid="4638956954852782576">"<Sans_titre>"</string>
- <string name="ellipsis" msgid="7899829516048813237">"..."</string>
- <string name="ellipsis_two_dots" msgid="1228078994866030736">"‥"</string>
<string name="emptyPhoneNumber" msgid="7694063042079676517">"(Aucun numéro de téléphone)"</string>
<string name="unknownName" msgid="2277556546742746522">"(Inconnu)"</string>
<string name="defaultVoiceMailAlphaTag" msgid="2660020990097733077">"Messagerie vocale"</string>
@@ -415,6 +413,8 @@
<string name="permdesc_bindRemoteDisplay" msgid="1261242718727295981">"Permet à l\'application autorisée de s\'associer à l\'interface de plus haut niveau d\'un écran distant. Les applications standards ne doivent jamais avoir recours à cette fonctionnalité."</string>
<string name="permlab_bindRemoteViews" msgid="5697987759897367099">"s\'associer à un service de widget"</string>
<string name="permdesc_bindRemoteViews" msgid="4717987810137692572">"Permet à l\'application autorisée de s\'associer à l\'interface de plus haut niveau d\'un service de widget. Les applications standards ne doivent jamais avoir recours à cette fonctionnalité."</string>
+ <string name="permlab_bindRouteProvider" msgid="4869394607915096847">"associer à un fournisseur d\'itinéraires enregistré"</string>
+ <string name="permdesc_bindRouteProvider" msgid="4703804520859960329">"Permet à l\'application autorisée de s\'associer à des fournisseurs d\'itinéraires enregistrés. Cette fonctionnalité ne devrait pas être nécessaire pour les applications standards."</string>
<string name="permlab_bindDeviceAdmin" msgid="8704986163711455010">"interagir avec l\'administrateur d\'un périphérique"</string>
<string name="permdesc_bindDeviceAdmin" msgid="569715419543907930">"Permet à l\'application autorisée d\'envoyer des intentions à l\'administrateur de l\'appareil. Les applications standards ne doivent jamais avoir recours à cette fonctionnalité."</string>
<string name="permlab_bindTvInput" msgid="5601264742478168987">"s\'associer à une entrée de téléviseur"</string>
@@ -742,6 +742,8 @@
<string name="permdesc_bindNotificationListenerService" msgid="985697918576902986">"Permet à l\'application de s\'associer à l\'interface de niveau supérieur d\'un service d\'écoute des notifications. Ne devrait jamais être nécessaire pour les applications normales."</string>
<string name="permlab_bindConditionProviderService" msgid="1180107672332704641">"s\'associer à un service de fournisseur de conditions"</string>
<string name="permdesc_bindConditionProviderService" msgid="1680513931165058425">"Permet à l\'application de s\'associer à l\'interface de niveau supérieur d\'un service de fournisseur de conditions. Ne devrait pas être nécessaire pour les applications standards."</string>
+ <string name="permlab_bindMediaRouteService" msgid="6637740382272686835">"s\'associer à un service d\'itinéraires multimédias"</string>
+ <string name="permdesc_bindMediaRouteService" msgid="6436655024972496687">"Permet à l\'application de s\'associer à l\'interface de niveau supérieur d\'un service d\'itinéraires multimédias. Ne devrait pas être nécessaire pour les applications standards."</string>
<string name="permlab_bindDreamService" msgid="4153646965978563462">"associer à un service de rêve"</string>
<string name="permdesc_bindDreamService" msgid="7325825272223347863">"Permet à l\'application autorisée de s\'associer à l\'interface de plus haut niveau d\'un service de rêve. Les applications standard ne devraient pas avoir recours à cette fonctionnalité."</string>
<string name="permlab_invokeCarrierSetup" msgid="3699600833975117478">"faire appel à l\'application de configuration du fournisseur de services"</string>
@@ -1283,6 +1285,9 @@
<skip />
<string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"Impossible de se connecter au Wi-Fi."</string>
<string name="wifi_watchdog_network_disabled_detailed" msgid="5548780776418332675">" dispose d\'une mauvaise connexion Internet."</string>
+ <string name="wifi_connect_alert_title" msgid="8455846016001810172">"Autoriser la connexion?"</string>
+ <string name="wifi_connect_alert_message" msgid="8930084523889618078">"%1$s souhaite se connecter à %2$s"</string>
+ <string name="wifi_connect_default_application" msgid="7143109390475484319">"Une application"</string>
<string name="wifi_p2p_dialog_title" msgid="97611782659324517">"Wi-Fi Direct"</string>
<string name="wifi_p2p_turnon_message" msgid="2909250942299627244">"Lancer le Wi-Fi Direct. Cela désactive le fonctionnement du Wi-Fi client ou via un point d\'accès."</string>
<string name="wifi_p2p_failed_message" msgid="3763669677935623084">"Impossible d\'activer le Wi-Fi Direct."</string>
@@ -1776,8 +1781,7 @@
<string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Demander le mot de passe avant d\'annuler l\'épinglage"</string>
<string name="battery_saver_description" msgid="2510530476513605742">"Pour optimiser l\'autonomie de la pile, l\'économiseur d\'énergie réduit les performances de votre appareil et limite les données en arrière-plan. Vous devrez peut-être ouvrir manuellement les applications de courriel, de messagerie et les autres applications synchronisées pour les mettre à jour.\n\nL\'économiseur d\'énergie se désactive automatiquement lorsque votre appareil est en charge."</string>
<string name="downtime_condition_summary" msgid="8761776337475705749">"Jusqu\'à ce que le temps d\'arrêt se termine à <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
- <!-- no translation found for downtime_condition_line_one (8762708714645352010) -->
- <skip />
+ <string name="downtime_condition_line_one" msgid="8762708714645352010">"Jusqu\'à la fin du temps d\'arrêt"</string>
<plurals name="zen_mode_duration_minutes_summary">
<item quantity="one" msgid="3177683545388923234">"Pendant une minute (jusqu\'à <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
<item quantity="other" msgid="2787867221129368935">"Pendant %1$d minutes (jusqu\'à <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
@@ -1797,8 +1801,6 @@
<string name="zen_mode_until" msgid="7336308492289875088">"Jusqu\'à <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
<string name="zen_mode_forever" msgid="4316804956488785559">"Indéfiniment"</string>
<string name="toolbar_collapse_description" msgid="2821479483960330739">"Réduire"</string>
- <!-- no translation found for zen_mode_next_alarm_summary (5915140424683747372) -->
- <skip />
- <!-- no translation found for zen_mode_next_alarm_line_one (5537042951553420916) -->
- <skip />
+ <string name="zen_mode_next_alarm_summary" msgid="5915140424683747372">"Jusqu\'à la prochaine alarme, à <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
+ <string name="zen_mode_next_alarm_line_one" msgid="5537042951553420916">"Jusqu\'à la prochaine alarme"</string>
</resources>
diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml
index 5dec636..0569b79 100644
--- a/core/res/res/values-fr/strings.xml
+++ b/core/res/res/values-fr/strings.xml
@@ -41,8 +41,6 @@
<string name="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g> s"</string>
<string name="durationSecond" msgid="985669622276420331">"<xliff:g id="SECONDS">%1$d</xliff:g> s"</string>
<string name="untitled" msgid="4638956954852782576">"<Sans nom>"</string>
- <string name="ellipsis" msgid="7899829516048813237">"…"</string>
- <string name="ellipsis_two_dots" msgid="1228078994866030736">"‥"</string>
<string name="emptyPhoneNumber" msgid="7694063042079676517">"(Aucun numéro de téléphone)"</string>
<string name="unknownName" msgid="2277556546742746522">"(Inconnu)"</string>
<string name="defaultVoiceMailAlphaTag" msgid="2660020990097733077">"Messagerie vocale"</string>
@@ -415,6 +413,8 @@
<string name="permdesc_bindRemoteDisplay" msgid="1261242718727295981">"Permettre à l\'application autorisée de s\'associer à l\'interface de niveau supérieur d\'un écran à distance. Cette fonctionnalité ne devrait pas être nécessaire pour les applications standards."</string>
<string name="permlab_bindRemoteViews" msgid="5697987759897367099">"associer à un service widget"</string>
<string name="permdesc_bindRemoteViews" msgid="4717987810137692572">"Permet à l\'application autorisée de s\'associer à l\'interface de plus haut niveau d\'un service widget. Les applications standards ne doivent jamais avoir recours à cette fonctionnalité."</string>
+ <string name="permlab_bindRouteProvider" msgid="4869394607915096847">"s\'associer à un fournisseur d\'itinéraires"</string>
+ <string name="permdesc_bindRouteProvider" msgid="4703804520859960329">"Permettre à l\'application autorisée de s\'associer à n\'importe quel fournisseur d\'itinéraires. Ne devrait pas être nécessaire pour les applications standards."</string>
<string name="permlab_bindDeviceAdmin" msgid="8704986163711455010">"interagir avec l\'administrateur du périphérique"</string>
<string name="permdesc_bindDeviceAdmin" msgid="569715419543907930">"Permet à l\'application autorisée d\'envoyer des intentions à l\'administrateur de l\'appareil. Les applications standards ne doivent jamais avoir recours à cette fonctionnalité."</string>
<string name="permlab_bindTvInput" msgid="5601264742478168987">"s\'associer à une entrée TV"</string>
@@ -742,6 +742,8 @@
<string name="permdesc_bindNotificationListenerService" msgid="985697918576902986">"Permet à l\'application de s\'associer à l\'interface de niveau supérieur d\'un service d\'écoute des notifications. Ne devrait jamais être nécessaire pour les applications normales."</string>
<string name="permlab_bindConditionProviderService" msgid="1180107672332704641">"s\'associer à un service de fournisseur de conditions"</string>
<string name="permdesc_bindConditionProviderService" msgid="1680513931165058425">"Permet à l\'application de s\'associer à l\'interface de niveau supérieur d\'un service de fournisseur de conditions. Ne devrait pas être nécessaire pour les applications standards."</string>
+ <string name="permlab_bindMediaRouteService" msgid="6637740382272686835">"s\'associer à un service d\'itinéraires médias"</string>
+ <string name="permdesc_bindMediaRouteService" msgid="6436655024972496687">"Permet à l\'application de s\'associer à l\'interface de niveau supérieur d\'un service d\'itinéraires médias. Ne devrait pas être nécessaire pour les applications standards."</string>
<string name="permlab_bindDreamService" msgid="4153646965978563462">"associer à un service d\'écran de veille interactif"</string>
<string name="permdesc_bindDreamService" msgid="7325825272223347863">"Permet à l\'application autorisée de s\'associer à l\'interface de plus haut niveau d\'un service d\'écran de veille interactif. Cette autorisation ne devrait jamais être nécessaire pour les applications standards."</string>
<string name="permlab_invokeCarrierSetup" msgid="3699600833975117478">"faire appel à l\'application de configuration fournie par l\'opérateur"</string>
@@ -1283,6 +1285,9 @@
<skip />
<string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"Impossible de se connecter au Wi-Fi."</string>
<string name="wifi_watchdog_network_disabled_detailed" msgid="5548780776418332675">" dispose d\'une mauvaise connexion Internet."</string>
+ <string name="wifi_connect_alert_title" msgid="8455846016001810172">"Autoriser la connexion ?"</string>
+ <string name="wifi_connect_alert_message" msgid="8930084523889618078">"%1$s souhaite se connecter à %2$s"</string>
+ <string name="wifi_connect_default_application" msgid="7143109390475484319">"Une application"</string>
<string name="wifi_p2p_dialog_title" msgid="97611782659324517">"Wi-Fi Direct"</string>
<string name="wifi_p2p_turnon_message" msgid="2909250942299627244">"Lancer le Wi-Fi Direct. Cela désactive le fonctionnement du Wi-Fi client ou via un point d\'accès."</string>
<string name="wifi_p2p_failed_message" msgid="3763669677935623084">"Impossible d\'activer le Wi-Fi Direct."</string>
@@ -1776,8 +1781,7 @@
<string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Demander le mot de passe avant d\'annuler l\'épinglage"</string>
<string name="battery_saver_description" msgid="2510530476513605742">"Pour optimiser l\'autonomie de la batterie, l\'économiseur de batterie réduit les performances de votre appareil et limite les données en arrière-plan. Vous devrez peut-être ouvrir manuellement vos applications d\'e-mail, de messagerie instantanée et autres applications synchronisées pour les mettre à jour.\n\nL\'économiseur de batterie s\'éteint automatiquement lorsque votre appareil est en charge."</string>
<string name="downtime_condition_summary" msgid="8761776337475705749">"Jusqu\'à ce que le temps d\'arrêt se termine à <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
- <!-- no translation found for downtime_condition_line_one (8762708714645352010) -->
- <skip />
+ <string name="downtime_condition_line_one" msgid="8762708714645352010">"Jusqu\'à la fin du temps d\'arrêt"</string>
<plurals name="zen_mode_duration_minutes_summary">
<item quantity="one" msgid="3177683545388923234">"Pendant une minute (jusqu\'à <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
<item quantity="other" msgid="2787867221129368935">"Pendant %1$d minutes (jusqu\'à <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
@@ -1797,8 +1801,6 @@
<string name="zen_mode_until" msgid="7336308492289875088">"Jusqu\'à <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
<string name="zen_mode_forever" msgid="4316804956488785559">"Indéfiniment"</string>
<string name="toolbar_collapse_description" msgid="2821479483960330739">"Réduire"</string>
- <!-- no translation found for zen_mode_next_alarm_summary (5915140424683747372) -->
- <skip />
- <!-- no translation found for zen_mode_next_alarm_line_one (5537042951553420916) -->
- <skip />
+ <string name="zen_mode_next_alarm_summary" msgid="5915140424683747372">"Jusqu\'à la prochaine alarme à <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
+ <string name="zen_mode_next_alarm_line_one" msgid="5537042951553420916">"Jusqu\'à la prochaine alarme"</string>
</resources>
diff --git a/core/res/res/values-gl-rES/strings.xml b/core/res/res/values-gl-rES/strings.xml
index d02f560..e3967ee 100644
--- a/core/res/res/values-gl-rES/strings.xml
+++ b/core/res/res/values-gl-rES/strings.xml
@@ -41,8 +41,6 @@
<string name="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g> segundos"</string>
<string name="durationSecond" msgid="985669622276420331">"<xliff:g id="SECONDS">%1$d</xliff:g> segundo"</string>
<string name="untitled" msgid="4638956954852782576">"<Sen título>"</string>
- <string name="ellipsis" msgid="7899829516048813237">"…"</string>
- <string name="ellipsis_two_dots" msgid="1228078994866030736">"…"</string>
<string name="emptyPhoneNumber" msgid="7694063042079676517">"(Sen número de teléfono)"</string>
<string name="unknownName" msgid="2277556546742746522">"(Descoñecido)"</string>
<string name="defaultVoiceMailAlphaTag" msgid="2660020990097733077">"Correo de voz"</string>
@@ -415,6 +413,8 @@
<string name="permdesc_bindRemoteDisplay" msgid="1261242718727295981">"Permite ao propietario vincularse á interface de nivel superior dunha pantalla remota. Non debería ser nunca necesario para as aplicacións normais."</string>
<string name="permlab_bindRemoteViews" msgid="5697987759897367099">"vincular a un servizo de widgets"</string>
<string name="permdesc_bindRemoteViews" msgid="4717987810137692572">"Permite ao propietario vincularse á interface de nivel superior dun servizo de widget. As aplicacións normais non deberían necesitar este permiso."</string>
+ <string name="permlab_bindRouteProvider" msgid="4869394607915096847">"vincular a un servizo de provedor de rutas"</string>
+ <string name="permdesc_bindRouteProvider" msgid="4703804520859960329">"Permite ao propietario vincularse a calquera provedor de ruta rexistrado. As aplicacións normais non deberían necesitar este permiso."</string>
<string name="permlab_bindDeviceAdmin" msgid="8704986163711455010">"interactuar cun administrador de dispositivos"</string>
<string name="permdesc_bindDeviceAdmin" msgid="569715419543907930">"Permite ao propietario enviar intentos a un administrador de dispositivos. As aplicacións normais non deberían necesitar este permiso."</string>
<string name="permlab_bindTvInput" msgid="5601264742478168987">"vincular a unha entrada de televisión"</string>
@@ -742,6 +742,8 @@
<string name="permdesc_bindNotificationListenerService" msgid="985697918576902986">"Permite ao propietario vincularse á interface de nivel superior dun servizo axente de escoita de notificacións. Non debería ser nunca necesario para as aplicacións normais."</string>
<string name="permlab_bindConditionProviderService" msgid="1180107672332704641">"vincular a un servizo de provedor de condicións"</string>
<string name="permdesc_bindConditionProviderService" msgid="1680513931165058425">"Permite ao propietario vincularse á interface de nivel superior dun servizo provedor de condicións. As aplicacións normais non deberían necesitar este permiso."</string>
+ <string name="permlab_bindMediaRouteService" msgid="6637740382272686835">"vincular a un servizo de ruta de medios"</string>
+ <string name="permdesc_bindMediaRouteService" msgid="6436655024972496687">"Permite ao propietario vincularse á interface de nivel superior dun servizo de ruta de medio. As aplicacións normais non deberían necesitar este permiso."</string>
<string name="permlab_bindDreamService" msgid="4153646965978563462">"vincular a un servizo de soños"</string>
<string name="permdesc_bindDreamService" msgid="7325825272223347863">"Permite ao propietario vincularse á interface de nivel superior dun servizo de soños. As aplicacións normais non deberían necesitar este permiso."</string>
<string name="permlab_invokeCarrierSetup" msgid="3699600833975117478">"invocar a aplicación de configuración fornecida polo operador"</string>
@@ -1283,6 +1285,9 @@
<skip />
<string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"Non se puido conectar coa rede Wi-Fi"</string>
<string name="wifi_watchdog_network_disabled_detailed" msgid="5548780776418332675">" ten unha conexión a Internet deficiente."</string>
+ <string name="wifi_connect_alert_title" msgid="8455846016001810172">"Queres permitir a conexión?"</string>
+ <string name="wifi_connect_alert_message" msgid="8930084523889618078">"%1$s quere conectarse a %2$s"</string>
+ <string name="wifi_connect_default_application" msgid="7143109390475484319">"Unha aplicación"</string>
<string name="wifi_p2p_dialog_title" msgid="97611782659324517">"Wi-Fi Direct"</string>
<string name="wifi_p2p_turnon_message" msgid="2909250942299627244">"Inicia Wi-Fi Direct. Esta acción desactivará o cliente e a zona interactiva da wifi."</string>
<string name="wifi_p2p_failed_message" msgid="3763669677935623084">"Non se puido iniciar Wi-Fi Direct."</string>
diff --git a/core/res/res/values-hi/strings.xml b/core/res/res/values-hi/strings.xml
index bf5f7e7..5a6d022 100644
--- a/core/res/res/values-hi/strings.xml
+++ b/core/res/res/values-hi/strings.xml
@@ -41,8 +41,6 @@
<string name="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g> सेकंड"</string>
<string name="durationSecond" msgid="985669622276420331">"<xliff:g id="SECONDS">%1$d</xliff:g> सेकंड"</string>
<string name="untitled" msgid="4638956954852782576">"<शीर्षक-रहित>"</string>
- <string name="ellipsis" msgid="7899829516048813237">"…"</string>
- <string name="ellipsis_two_dots" msgid="1228078994866030736">"‥"</string>
<string name="emptyPhoneNumber" msgid="7694063042079676517">"(कोई फ़ोन नंबर नहीं)"</string>
<string name="unknownName" msgid="2277556546742746522">"(अज्ञात)"</string>
<string name="defaultVoiceMailAlphaTag" msgid="2660020990097733077">"वॉयस मेल"</string>
@@ -415,6 +413,8 @@
<string name="permdesc_bindRemoteDisplay" msgid="1261242718727295981">"धारक को किसी रिमोट डिस्प्ले के शीर्ष-स्तरीय इंटरफ़ेस से आबद्ध होने देती है. सामान्य ऐप्स के लिए कभी भी आवश्यक नहीं होना चाहिए."</string>
<string name="permlab_bindRemoteViews" msgid="5697987759897367099">"किसी विजेट सेवा से आबद्ध करें"</string>
<string name="permdesc_bindRemoteViews" msgid="4717987810137692572">"धारक को किसी विजेट सेवा के शीर्ष-स्तर इंटरफ़ेस से आबद्ध होने देता है. सामान्य ऐप्स के लिए कभी भी आवश्यक नहीं होना चाहिए."</string>
+ <string name="permlab_bindRouteProvider" msgid="4869394607915096847">"किसी रूट प्रदाता सेवा से आबद्ध हों"</string>
+ <string name="permdesc_bindRouteProvider" msgid="4703804520859960329">"धारक को किसी भी पंजीकृत रूट प्रदाता से आबद्ध रहने देती है. सामान्य ऐप्स के लिए कभी भी आवश्यक नहीं होना चाहिए."</string>
<string name="permlab_bindDeviceAdmin" msgid="8704986163711455010">"किसी डिवाइस नियंत्रक के साथ सहभागिता करें"</string>
<string name="permdesc_bindDeviceAdmin" msgid="569715419543907930">"धारक को किसी डिवाइस नियंत्रक को उद्देश्य भेजने देता है. सामान्य ऐप्स के लिए कभी भी आवश्यक नहीं होना चाहिए."</string>
<string name="permlab_bindTvInput" msgid="5601264742478168987">"टीवी इनपुट से आबद्ध करें"</string>
@@ -742,6 +742,8 @@
<string name="permdesc_bindNotificationListenerService" msgid="985697918576902986">"धारक को नोटिफिकेशन श्रवणकर्ता सेवा के शीर्ष स्तरीय इंटरफ़ेस से जुड़ने देती है. सामान्य ऐप्स के लिए कभी भी आवश्यक नहीं होनी चाहिए."</string>
<string name="permlab_bindConditionProviderService" msgid="1180107672332704641">"किसी स्थिति प्रदाता सेवा से आबद्ध हों"</string>
<string name="permdesc_bindConditionProviderService" msgid="1680513931165058425">"धारक को किसी स्थिति प्रदाता सेवा के शीर्ष-स्तर के इंटरफ़ेस से आबद्ध होने देती है. सामान्य ऐप्स के लिए कभी भी आवश्यक नहीं होना चाहिए."</string>
+ <string name="permlab_bindMediaRouteService" msgid="6637740382272686835">"मीडिया रूट सेवा से आबद्ध हों"</string>
+ <string name="permdesc_bindMediaRouteService" msgid="6436655024972496687">"धारक को मीडिया रूट सेवा के शीर्ष-स्तर के इंटरफ़ेस से आबद्ध होने देती है. सामान्य ऐप्स के लिए कभी भी आवश्यक नहीं होना चाहिए."</string>
<string name="permlab_bindDreamService" msgid="4153646965978563462">"भावी सेवा से आबद्ध करें"</string>
<string name="permdesc_bindDreamService" msgid="7325825272223347863">"धारक को किसी भावी सेवा के शीर्ष-स्तर इंटरफ़ेस से आबद्ध होने देता है. सामान्य ऐप्स के लिए कभी भी आवश्यक नहीं होना चाहिए."</string>
<string name="permlab_invokeCarrierSetup" msgid="3699600833975117478">"वाहक के द्वारा उपलब्ध कराया गया कॉन्फ़िगरेशन ऐप्स प्रारंभ करें"</string>
@@ -1283,6 +1285,9 @@
<skip />
<string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"वाई-फ़ाई से कनेक्ट नहीं हो सका"</string>
<string name="wifi_watchdog_network_disabled_detailed" msgid="5548780776418332675">" के पास एक कमज़ोर इंटरनेट कनेक्शन है."</string>
+ <string name="wifi_connect_alert_title" msgid="8455846016001810172">"कनेक्शन की अनुमति दें?"</string>
+ <string name="wifi_connect_alert_message" msgid="8930084523889618078">"%1$s, %2$s से कनेक्ट होना चाहता/चाहती है"</string>
+ <string name="wifi_connect_default_application" msgid="7143109390475484319">"ऐप्लिकेशन"</string>
<string name="wifi_p2p_dialog_title" msgid="97611782659324517">"वाई-फ़ाई डायरेक्ट"</string>
<string name="wifi_p2p_turnon_message" msgid="2909250942299627244">"वाई-फ़ाई डायरेक्ट प्रारंभ करें. इससे वाई-फ़ाई क्लाइंट/हॉटस्पॉट कार्यवाही बंद हो जाएगी."</string>
<string name="wifi_p2p_failed_message" msgid="3763669677935623084">"वाई-फ़ाई डायरेक्ट प्रारंभ नहीं किया जा सका."</string>
@@ -1776,8 +1781,7 @@
<string name="lock_to_app_unlock_password" msgid="6380979775916974414">"अनपिन करने से पहले पासवर्ड के लिए पूछें"</string>
<string name="battery_saver_description" msgid="2510530476513605742">"बैटरी के जीवन काल को बेहतर बनाने में सहायता के लिए, बैटरी सेवर आपके डिवाइस के प्रदर्शन को घटा देता है तथा कंपन और अधिकांश पृष्ठभूमि डेटा को सीमित कर देता है. ईमेल, संदेश सेवा और अन्य ऐप्स जो समन्वयन पर निर्भर करते हैं वे तब तक अपडेट नहीं हो सकते जब तक कि आप उन्हें नहीं खोलते.\n\nजब आपका डिवाइस चार्ज हो रहा होता है तो बैटरी सेवर अपने आप बंद हो जाता है."</string>
<string name="downtime_condition_summary" msgid="8761776337475705749">"जब तक कि <xliff:g id="FORMATTEDTIME">%1$s</xliff:g> बजे आपका डाउनटाइम समाप्त न हो"</string>
- <!-- no translation found for downtime_condition_line_one (8762708714645352010) -->
- <skip />
+ <string name="downtime_condition_line_one" msgid="8762708714645352010">"आपका बंद रहने का समय समाप्त होने तक"</string>
<plurals name="zen_mode_duration_minutes_summary">
<item quantity="one" msgid="3177683545388923234">"एक मिनट के लिए (<xliff:g id="FORMATTEDTIME">%2$s</xliff:g> तक)"</item>
<item quantity="other" msgid="2787867221129368935">"%1$d मिनट के लिए (<xliff:g id="FORMATTEDTIME">%2$s</xliff:g> तक)"</item>
@@ -1797,8 +1801,6 @@
<string name="zen_mode_until" msgid="7336308492289875088">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g> तक"</string>
<string name="zen_mode_forever" msgid="4316804956488785559">"अनिश्चित समय तक"</string>
<string name="toolbar_collapse_description" msgid="2821479483960330739">"संक्षिप्त करें"</string>
- <!-- no translation found for zen_mode_next_alarm_summary (5915140424683747372) -->
- <skip />
- <!-- no translation found for zen_mode_next_alarm_line_one (5537042951553420916) -->
- <skip />
+ <string name="zen_mode_next_alarm_summary" msgid="5915140424683747372">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g> पर अगले अलार्म तक"</string>
+ <string name="zen_mode_next_alarm_line_one" msgid="5537042951553420916">"अगले अलार्म तक"</string>
</resources>
diff --git a/core/res/res/values-hr/strings.xml b/core/res/res/values-hr/strings.xml
index a9ab2e4..a98b2aa 100644
--- a/core/res/res/values-hr/strings.xml
+++ b/core/res/res/values-hr/strings.xml
@@ -41,8 +41,6 @@
<string name="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g> s"</string>
<string name="durationSecond" msgid="985669622276420331">"<xliff:g id="SECONDS">%1$d</xliff:g> s"</string>
<string name="untitled" msgid="4638956954852782576">"<Bez naslova>"</string>
- <string name="ellipsis" msgid="7899829516048813237">"…"</string>
- <string name="ellipsis_two_dots" msgid="1228078994866030736">"‥"</string>
<string name="emptyPhoneNumber" msgid="7694063042079676517">"(Nema telefonskog broja)"</string>
<string name="unknownName" msgid="2277556546742746522">"(Nepoznato)"</string>
<string name="defaultVoiceMailAlphaTag" msgid="2660020990097733077">"Govorna pošta"</string>
@@ -415,6 +413,8 @@
<string name="permdesc_bindRemoteDisplay" msgid="1261242718727295981">"Nositelju omogućuje vezanje uza sučelje najviše razine udaljenog zaslona. Ne bi smjelo biti potrebno za normalne aplikacije."</string>
<string name="permlab_bindRemoteViews" msgid="5697987759897367099">"vezanje na uslugu widgeta"</string>
<string name="permdesc_bindRemoteViews" msgid="4717987810137692572">"Nositelju omogućuje vezanje uz sučelje najviše razine usluge widgeta. Ne bi smjelo biti potrebno za normalne aplikacije."</string>
+ <string name="permlab_bindRouteProvider" msgid="4869394607915096847">"povezivanje s davateljem usluge usmjeravanja poziva"</string>
+ <string name="permdesc_bindRouteProvider" msgid="4703804520859960329">"Nositelju omogućuje povezivanje s registriranim davateljem usluga usmjeravanja poziva. Nije potrebno za normalne aplikacije."</string>
<string name="permlab_bindDeviceAdmin" msgid="8704986163711455010">"interakcija s administratorom uređaja"</string>
<string name="permdesc_bindDeviceAdmin" msgid="569715419543907930">"Nositelju omogućuje slanje namjera administratoru uređaja. Ne bi smjelo biti potrebno za normalne aplikacije."</string>
<string name="permlab_bindTvInput" msgid="5601264742478168987">"povezivanje s TV ulazom"</string>
@@ -742,6 +742,8 @@
<string name="permdesc_bindNotificationListenerService" msgid="985697918576902986">"Nositelju omogućuje vezanje uz sučelje najviše razine usluge slušatelja obavijesti. Ne bi smjelo biti potrebno za uobičajene aplikacije."</string>
<string name="permlab_bindConditionProviderService" msgid="1180107672332704641">"povezivanje s uslugom davatelja uvjeta"</string>
<string name="permdesc_bindConditionProviderService" msgid="1680513931165058425">"Vlasniku omogućuje povezivanje sa sučeljem najviše razine usluge davatelja uvjeta. Nije potrebno za normalne aplikacije."</string>
+ <string name="permlab_bindMediaRouteService" msgid="6637740382272686835">"povezivanje s uslugom za usmjeravanje medija"</string>
+ <string name="permdesc_bindMediaRouteService" msgid="6436655024972496687">"Korisniku omogućuje vezanje uz sučelje najviše razine usluge za usmjeravanje medija. Ne bi smjelo biti potrebno za uobičajene aplikacije."</string>
<string name="permlab_bindDreamService" msgid="4153646965978563462">"vezanje na Dream"</string>
<string name="permdesc_bindDreamService" msgid="7325825272223347863">"Vlasniku omogućuje povezivanje sa sučeljem najviše razine za Dream. Ne bi trebalo biti potrebno za normalne aplikacije."</string>
<string name="permlab_invokeCarrierSetup" msgid="3699600833975117478">"pozovi operaterovu aplikaciju za konfiguraciju"</string>
@@ -1283,6 +1285,9 @@
<skip />
<string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"Ne može se spojiti na Wi-Fi"</string>
<string name="wifi_watchdog_network_disabled_detailed" msgid="5548780776418332675">" ima lošu internetsku vezu."</string>
+ <string name="wifi_connect_alert_title" msgid="8455846016001810172">"Dopustiti povezivanje?"</string>
+ <string name="wifi_connect_alert_message" msgid="8930084523889618078">"%1$s traži povezivanje sa sljedećim: %2$s"</string>
+ <string name="wifi_connect_default_application" msgid="7143109390475484319">"Aplikacija"</string>
<string name="wifi_p2p_dialog_title" msgid="97611782659324517">"Izravni Wi-Fi"</string>
<string name="wifi_p2p_turnon_message" msgid="2909250942299627244">"Pokreni izravan rad s Wi-Fi mrežom. To će isključiti rad s Wi-Fi klijentom/žarišnom točkom."</string>
<string name="wifi_p2p_failed_message" msgid="3763669677935623084">"Pokretanje izravne Wi-Fi veze nije moguće."</string>
@@ -1776,8 +1781,7 @@
<string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Traži zaporku radi otkvačivanja"</string>
<string name="battery_saver_description" msgid="2510530476513605742">"Da bi se produljilo trajanje baterije, ušteda baterije smanjuje rad uređaja i ograničava vibraciju i većinu pozadinskih podataka. Aplikacije za e-poštu, slanje poruka i ostalo koje se oslanjaju na sinkronizaciju možda se neće ažurirati ako ih ne otvorite.\n\nUšteda baterije isključuje se automatski dok se uređaj puni."</string>
<string name="downtime_condition_summary" msgid="8761776337475705749">"Dok razdoblje zastoja ne završi u <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
- <!-- no translation found for downtime_condition_line_one (8762708714645352010) -->
- <skip />
+ <string name="downtime_condition_line_one" msgid="8762708714645352010">"Do završetka prekida rada"</string>
<plurals name="zen_mode_duration_minutes_summary">
<item quantity="one" msgid="3177683545388923234">"Jednu minutu (do <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
<item quantity="other" msgid="2787867221129368935">"%1$d min (do <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
@@ -1797,8 +1801,6 @@
<string name="zen_mode_until" msgid="7336308492289875088">"Do <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
<string name="zen_mode_forever" msgid="4316804956488785559">"Neodređeno"</string>
<string name="toolbar_collapse_description" msgid="2821479483960330739">"Sažmi"</string>
- <!-- no translation found for zen_mode_next_alarm_summary (5915140424683747372) -->
- <skip />
- <!-- no translation found for zen_mode_next_alarm_line_one (5537042951553420916) -->
- <skip />
+ <string name="zen_mode_next_alarm_summary" msgid="5915140424683747372">"Do sljedećeg alarma u <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
+ <string name="zen_mode_next_alarm_line_one" msgid="5537042951553420916">"Do sljedećeg alarma"</string>
</resources>
diff --git a/core/res/res/values-hu/strings.xml b/core/res/res/values-hu/strings.xml
index 8814e2d..38b6a51 100644
--- a/core/res/res/values-hu/strings.xml
+++ b/core/res/res/values-hu/strings.xml
@@ -41,8 +41,6 @@
<string name="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g> másodperc"</string>
<string name="durationSecond" msgid="985669622276420331">"<xliff:g id="SECONDS">%1$d</xliff:g> másodperc"</string>
<string name="untitled" msgid="4638956954852782576">"<Névtelen>"</string>
- <string name="ellipsis" msgid="7899829516048813237">"…"</string>
- <string name="ellipsis_two_dots" msgid="1228078994866030736">"‥"</string>
<string name="emptyPhoneNumber" msgid="7694063042079676517">"(Nincs telefonszám)"</string>
<string name="unknownName" msgid="2277556546742746522">"(Ismeretlen)"</string>
<string name="defaultVoiceMailAlphaTag" msgid="2660020990097733077">"Hangposta"</string>
@@ -415,6 +413,8 @@
<string name="permdesc_bindRemoteDisplay" msgid="1261242718727295981">"Lehetővé teszi a használó számára, hogy csatlakozzon egy távoli kijelző legfelső szintű kezelőfelületéhez. A normál alkalmazásoknak erre soha nincs szükségük."</string>
<string name="permlab_bindRemoteViews" msgid="5697987759897367099">"csatlakozás modulszolgáltatáshoz"</string>
<string name="permdesc_bindRemoteViews" msgid="4717987810137692572">"Lehetővé teszi a használó számára, hogy csatlakozzon egy modulszolgáltatás legfelső szintű kezelőfelületéhez. A normál alkalmazásoknak erre soha nincs szüksége."</string>
+ <string name="permlab_bindRouteProvider" msgid="4869394607915096847">"csatlakozás egy útvonal-szolgáltatóhoz"</string>
+ <string name="permdesc_bindRouteProvider" msgid="4703804520859960329">"Az eszköz kezelője csatlakozhat bármely regisztrált útvonal-szolgáltatóhoz. A normál alkalmazások esetében erre nincs szükség."</string>
<string name="permlab_bindDeviceAdmin" msgid="8704986163711455010">"az eszközkezelő használata"</string>
<string name="permdesc_bindDeviceAdmin" msgid="569715419543907930">"Lehetővé teszi a tulajdonos számára, hogy célokat küldjön egy eszközkezelőnek. A normál alkalmazásoknak erre soha nincs szüksége."</string>
<string name="permlab_bindTvInput" msgid="5601264742478168987">"csatlakozás tévébemenethez"</string>
@@ -742,6 +742,8 @@
<string name="permdesc_bindNotificationListenerService" msgid="985697918576902986">"Lehetővé teszi a használó számára, hogy csatlakozzon egy értesítésfigyelő szolgáltatás legfelső szintű felületéhez. A normál alkalmazásoknak erre soha nincs szükségük."</string>
<string name="permlab_bindConditionProviderService" msgid="1180107672332704641">"csatlakozás egy feltételbiztosító szolgáltatáshoz"</string>
<string name="permdesc_bindConditionProviderService" msgid="1680513931165058425">"Lehetővé teszi a használó számára, hogy csatlakozzon egy feltételbiztosító szolgáltatás legfelső szintű kezelőfelületéhez. A normál alkalmazásoknak erre soha nincs szükségük."</string>
+ <string name="permlab_bindMediaRouteService" msgid="6637740382272686835">"csatlakozás egy médiaútvonal-szolgáltatáshoz"</string>
+ <string name="permdesc_bindMediaRouteService" msgid="6436655024972496687">"Lehetővé teszi a használó számára, hogy csatlakozzon egy médiaútvonal-szolgáltatás legfelső szintű kezelőfelületéhez. A normál alkalmazásoknak erre soha nincs szükségük."</string>
<string name="permlab_bindDreamService" msgid="4153646965978563462">"csatlakozás egy képernyővédő szolgáltatáshoz"</string>
<string name="permdesc_bindDreamService" msgid="7325825272223347863">"Lehetővé teszi a használó számára, hogy csatlakozzon egy képernyővédő szolgáltatás legfelső szintű kezelőfelületéhez. A normál alkalmazásoknak erre soha nincs szükségük."</string>
<string name="permlab_invokeCarrierSetup" msgid="3699600833975117478">"a szolgáltatói konfigurációs alkalmazás hívása"</string>
@@ -1283,6 +1285,9 @@
<skip />
<string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"Nem sikerült csatlakozni a Wi-Fi hálózathoz"</string>
<string name="wifi_watchdog_network_disabled_detailed" msgid="5548780776418332675">" rossz internetkapcsolattal rendelkezik."</string>
+ <string name="wifi_connect_alert_title" msgid="8455846016001810172">"Engedélyezi a csatlakozást?"</string>
+ <string name="wifi_connect_alert_message" msgid="8930084523889618078">"A(z)%1$s szeretne csatlakozni a következőhöz: %2$s"</string>
+ <string name="wifi_connect_default_application" msgid="7143109390475484319">"Egy alkalmazás"</string>
<string name="wifi_p2p_dialog_title" msgid="97611782659324517">"Wi-Fi Direct"</string>
<string name="wifi_p2p_turnon_message" msgid="2909250942299627244">"Wi-Fi Direct elindítása. A Wi-Fi kliens/hotspot ettől leáll."</string>
<string name="wifi_p2p_failed_message" msgid="3763669677935623084">"Nem sikerült elindítani a Wi-Fi Direct kapcsolatot."</string>
@@ -1776,8 +1781,7 @@
<string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Jelszó kérése a rögzítés feloldásához"</string>
<string name="battery_saver_description" msgid="2510530476513605742">"Az akkumulátor üzemidejének növeléséhez az akkumulátorkímélő mód csökkenti az eszköz teljesítményét, valamint korlátozza a rezgést és a legtöbb háttéradatot. Előfordulhat, hogy az e-mailek, az üzenetküldő programok és más alkalmazások, amelyek a szinkronizálás funkciót használják, nem frissülnek addig, amíg meg nem nyitja őket.\n\nAz akkumulátorkímélő mód automatikusan kikapcsol, amikor az eszköz töltődik."</string>
<string name="downtime_condition_summary" msgid="8761776337475705749">"Amíg az állásidő véget nem ér ekkor: <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
- <!-- no translation found for downtime_condition_line_one (8762708714645352010) -->
- <skip />
+ <string name="downtime_condition_line_one" msgid="8762708714645352010">"Amíg az inaktivitás véget nem ér"</string>
<plurals name="zen_mode_duration_minutes_summary">
<item quantity="one" msgid="3177683545388923234">"Egy percre (eddig: <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
<item quantity="other" msgid="2787867221129368935">"%1$d percre (eddig: <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
@@ -1797,8 +1801,6 @@
<string name="zen_mode_until" msgid="7336308492289875088">"Eddig: <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
<string name="zen_mode_forever" msgid="4316804956488785559">"Határozatlan ideig"</string>
<string name="toolbar_collapse_description" msgid="2821479483960330739">"Összecsukás"</string>
- <!-- no translation found for zen_mode_next_alarm_summary (5915140424683747372) -->
- <skip />
- <!-- no translation found for zen_mode_next_alarm_line_one (5537042951553420916) -->
- <skip />
+ <string name="zen_mode_next_alarm_summary" msgid="5915140424683747372">"A következő ébresztésig ekkor: <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
+ <string name="zen_mode_next_alarm_line_one" msgid="5537042951553420916">"A következő ébresztésig"</string>
</resources>
diff --git a/core/res/res/values-hy-rAM/strings.xml b/core/res/res/values-hy-rAM/strings.xml
index 4871252..3b96a4f 100644
--- a/core/res/res/values-hy-rAM/strings.xml
+++ b/core/res/res/values-hy-rAM/strings.xml
@@ -41,8 +41,6 @@
<string name="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g> վ"</string>
<string name="durationSecond" msgid="985669622276420331">"<xliff:g id="SECONDS">%1$d</xliff:g> վ"</string>
<string name="untitled" msgid="4638956954852782576">"<Անանուն>"</string>
- <string name="ellipsis" msgid="7899829516048813237">"…"</string>
- <string name="ellipsis_two_dots" msgid="1228078994866030736">"‥"</string>
<string name="emptyPhoneNumber" msgid="7694063042079676517">"(Հեռախոսահամար չկա)"</string>
<string name="unknownName" msgid="2277556546742746522">"(Անհայտ)"</string>
<string name="defaultVoiceMailAlphaTag" msgid="2660020990097733077">"Ձայնային փոստ"</string>
@@ -415,6 +413,8 @@
<string name="permdesc_bindRemoteDisplay" msgid="1261242718727295981">"Թույլ է տալիս սեփականատիրոջը միանալ հեռակա էկրանի վերին մակարդակի ինտերֆեյսին: Սովորական ծրագրերի համար երբևէ չպետք է անհրաժեշտ լինի:"</string>
<string name="permlab_bindRemoteViews" msgid="5697987759897367099">"միանալ վիջեթ ծառայությանը"</string>
<string name="permdesc_bindRemoteViews" msgid="4717987810137692572">"Թույլ է տալիս սեփականատիրոջը միանալ վիջեթ ծառայության վերին մակարդակի ինտերֆեյսին: Սովորական հավելվածների համար երբևէ չպետք է անհրաժեշտ լինի:"</string>
+ <string name="permlab_bindRouteProvider" msgid="4869394607915096847">"կապվել երթուղու մատակարարի ծառայությանը"</string>
+ <string name="permdesc_bindRouteProvider" msgid="4703804520859960329">"Թույլ է տալիս տիրոջը կապվել երթուղու մատակարարներից ցանկացածին: Սովորական ծրագրերի համար երբեք անհրաժեշտ չէ:"</string>
<string name="permlab_bindDeviceAdmin" msgid="8704986163711455010">"փոխգործակցել սարքի կառավարչի հետ"</string>
<string name="permdesc_bindDeviceAdmin" msgid="569715419543907930">"Թույլ է տալիս սեփականատիրոջը ուղարկել մտադրություններ սարքի կառավարչին: Սովորական հավելվածների համար երբևէ չպետք է անհրաժեշտ լինի:"</string>
<string name="permlab_bindTvInput" msgid="5601264742478168987">"միանալ հեռուստացույցի մուտքին"</string>
@@ -742,6 +742,8 @@
<string name="permdesc_bindNotificationListenerService" msgid="985697918576902986">"Թույլ է տալիս սեփականատիրոջը միանալ ծանուցումները ունկնդրող ծառայության վերին մակարդակի ինտերֆեյսին: Սովորական հավելվածների համար երբևէ չպետք է անհրաժեշտ լինի:"</string>
<string name="permlab_bindConditionProviderService" msgid="1180107672332704641">"կապվել պայմանների մատակարարի ծառայությանը"</string>
<string name="permdesc_bindConditionProviderService" msgid="1680513931165058425">"Թույլ է տալիս սեփականատիրոջը միանալ պայմանների մատակարարների բազային միջերեսին: Սովորական ծրագրերի համար երբևէ չպետք է անհրաժեշտ լինի:"</string>
+ <string name="permlab_bindMediaRouteService" msgid="6637740382272686835">"կապվել մեդիա երթուղու ծառայությանը"</string>
+ <string name="permdesc_bindMediaRouteService" msgid="6436655024972496687">"Թույլ է տալիս սեփականատիրոջը միանալ մեդիա երթուղու ծառայության բազային միջերեսին: Սովորական ծրագրերի համար երբևէ չպետք է անհրաժեշտ լինի:"</string>
<string name="permlab_bindDreamService" msgid="4153646965978563462">"Միացում էկրանապահների ծառայությանը"</string>
<string name="permdesc_bindDreamService" msgid="7325825272223347863">"Թույլ է տալիս սեփականատիրոջը միանալ էկրանապահների ծառայության վերին մակարդակի միջերեսին: Սովորական ծրագրերի համար երբևէ չպետք է անհրաժեշտ լինի:"</string>
<string name="permlab_invokeCarrierSetup" msgid="3699600833975117478">"գործարկել օպերատորի կողմից տրամադրված կազմաձևման ծրագիրը"</string>
@@ -1283,6 +1285,9 @@
<skip />
<string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"Չհաջողվեց միանալ Wi-Fi-ին"</string>
<string name="wifi_watchdog_network_disabled_detailed" msgid="5548780776418332675">" ունի թույլ ինտերնետ կապ:"</string>
+ <string name="wifi_connect_alert_title" msgid="8455846016001810172">"Թույլատրե՞լ կապը:"</string>
+ <string name="wifi_connect_alert_message" msgid="8930084523889618078">"%1$s օգտվողը ցանկանում է կապվել %2$s-ին"</string>
+ <string name="wifi_connect_default_application" msgid="7143109390475484319">"Հավելված"</string>
<string name="wifi_p2p_dialog_title" msgid="97611782659324517">"Wi-Fi ուղիղ"</string>
<string name="wifi_p2p_turnon_message" msgid="2909250942299627244">"Մեկնարկել Wi-Fi ուղին: Այն կանջատի Wi-Fi հաճախորդ/թեժ կետ գործողությունը:"</string>
<string name="wifi_p2p_failed_message" msgid="3763669677935623084">"Չհաջողվեց մեկնարկել Wi-Fi ուղին:"</string>
diff --git a/core/res/res/values-in/strings.xml b/core/res/res/values-in/strings.xml
index ff59614..b901168 100644
--- a/core/res/res/values-in/strings.xml
+++ b/core/res/res/values-in/strings.xml
@@ -41,8 +41,6 @@
<string name="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g> dtk"</string>
<string name="durationSecond" msgid="985669622276420331">"<xliff:g id="SECONDS">%1$d</xliff:g> dtk"</string>
<string name="untitled" msgid="4638956954852782576">"<Tanpa judul>"</string>
- <string name="ellipsis" msgid="7899829516048813237">"…"</string>
- <string name="ellipsis_two_dots" msgid="1228078994866030736">"‥"</string>
<string name="emptyPhoneNumber" msgid="7694063042079676517">"(Tidak ada nomor telepon)"</string>
<string name="unknownName" msgid="2277556546742746522">"(Tidak diketahui)"</string>
<string name="defaultVoiceMailAlphaTag" msgid="2660020990097733077">"Kotak Pesan"</string>
@@ -415,6 +413,8 @@
<string name="permdesc_bindRemoteDisplay" msgid="1261242718727295981">"Mengizinkan pemegang mengikat ke antarmuka tingkat atas dari layar jarak jauh. Tidak pernah diperlukan untuk aplikasi normal."</string>
<string name="permlab_bindRemoteViews" msgid="5697987759897367099">"mengikat ke layanan widget"</string>
<string name="permdesc_bindRemoteViews" msgid="4717987810137692572">"Mengizinkan pemegang mengikat antarmuka tingkat tinggi dari suatu layanan widget. Tidak pernah diperlukan oleh apl normal."</string>
+ <string name="permlab_bindRouteProvider" msgid="4869394607915096847">"mengikat ke layanan penyedia rute"</string>
+ <string name="permdesc_bindRouteProvider" msgid="4703804520859960329">"Memungkinkan pemegang mengikat ke penyedia rute terdaftar mana pun. Tidak pernah dibutuhkan untuk aplikasi normal."</string>
<string name="permlab_bindDeviceAdmin" msgid="8704986163711455010">"berinteraksi dengan admin perangkat"</string>
<string name="permdesc_bindDeviceAdmin" msgid="569715419543907930">"Mengizinkan pemegang mengirimkan tujuan kepada administrator perangkat. Tidak pernah diperlukan oleh apl normal."</string>
<string name="permlab_bindTvInput" msgid="5601264742478168987">"mengikat ke masukan TV"</string>
@@ -742,6 +742,8 @@
<string name="permdesc_bindNotificationListenerService" msgid="985697918576902986">"Memungkinkan pemegang mengikat antarmuka tingkat teratas dari suatu layanan pendengar pemberitahuan. Tidak pernah diperlukan oleh aplikasi normal."</string>
<string name="permlab_bindConditionProviderService" msgid="1180107672332704641">"mengikat ke layanan penyedia ketentuan"</string>
<string name="permdesc_bindConditionProviderService" msgid="1680513931165058425">"Memungkinkan pemegang mengikat antarmuka tingkat tinggi dari layanan penyedia ketentuan. Tidak pernah diperlukan oleh aplikasi normal."</string>
+ <string name="permlab_bindMediaRouteService" msgid="6637740382272686835">"mengikat ke layanan rute media"</string>
+ <string name="permdesc_bindMediaRouteService" msgid="6436655024972496687">"Memungkinkan pemegang mengikat antarmuka tingkat tinggi dari layanan rute media. Tidak pernah diperlukan oleh aplikasi normal."</string>
<string name="permlab_bindDreamService" msgid="4153646965978563462">"mengikat ke layanan lamunan"</string>
<string name="permdesc_bindDreamService" msgid="7325825272223347863">"Memungkinkan pemegang mengikat antarmuka tingkat tinggi dari suatu layanan lamunan. Tidak pernah diperlukan oleh aplikasi normal."</string>
<string name="permlab_invokeCarrierSetup" msgid="3699600833975117478">"memanggil aplikasi konfigurasi yang disediakan operator"</string>
@@ -1283,6 +1285,9 @@
<skip />
<string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"Tidak dapat tersambung ke Wi-Fi"</string>
<string name="wifi_watchdog_network_disabled_detailed" msgid="5548780776418332675">" memiliki sambungan internet yang buruk."</string>
+ <string name="wifi_connect_alert_title" msgid="8455846016001810172">"Izinkan hubungan?"</string>
+ <string name="wifi_connect_alert_message" msgid="8930084523889618078">"%1$s ingin terhubung ke %2$s"</string>
+ <string name="wifi_connect_default_application" msgid="7143109390475484319">"Aplikasi"</string>
<string name="wifi_p2p_dialog_title" msgid="97611782659324517">"Wi-Fi Direct"</string>
<string name="wifi_p2p_turnon_message" msgid="2909250942299627244">"Memulai Wi-Fi Direct. Opsi ini akan mematikan hotspot/klien Wi-Fi."</string>
<string name="wifi_p2p_failed_message" msgid="3763669677935623084">"Tidak dapat memulai Wi-Fi Direct."</string>
diff --git a/core/res/res/values-is-rIS/strings.xml b/core/res/res/values-is-rIS/strings.xml
index 3f43bd4..cf2e9cc 100644
--- a/core/res/res/values-is-rIS/strings.xml
+++ b/core/res/res/values-is-rIS/strings.xml
@@ -41,8 +41,6 @@
<string name="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g> sek."</string>
<string name="durationSecond" msgid="985669622276420331">"<xliff:g id="SECONDS">%1$d</xliff:g> sek."</string>
<string name="untitled" msgid="4638956954852782576">"<Ónefnt>"</string>
- <string name="ellipsis" msgid="7899829516048813237">"…"</string>
- <string name="ellipsis_two_dots" msgid="1228078994866030736">"‥"</string>
<string name="emptyPhoneNumber" msgid="7694063042079676517">"(Ekkert símanúmer)"</string>
<string name="unknownName" msgid="2277556546742746522">"(Óþekkt)"</string>
<string name="defaultVoiceMailAlphaTag" msgid="2660020990097733077">"Talhólf"</string>
@@ -415,6 +413,8 @@
<string name="permdesc_bindRemoteDisplay" msgid="1261242718727295981">"Leyfir forriti að bindast efsta viðmótslagi fjartengds skjás. Ætti aldrei að vera nauðsynlegt fyrir venjuleg forrit."</string>
<string name="permlab_bindRemoteViews" msgid="5697987759897367099">"bindast græjuþjónustu"</string>
<string name="permdesc_bindRemoteViews" msgid="4717987810137692572">"Leyfir handhafa að bindast efsta viðmótslagi græjuþjónustu. Ætti aldrei að vera nauðsynlegt fyrir venjuleg forrit."</string>
+ <string name="permlab_bindRouteProvider" msgid="4869394607915096847">"bindast þjónustu leiðaveitu"</string>
+ <string name="permdesc_bindRouteProvider" msgid="4703804520859960329">"Leyfir handhafa að bindast öllum veitum skráðra leiða. Ætti aldrei að vera nauðsynlegt fyrir venjuleg forrit."</string>
<string name="permlab_bindDeviceAdmin" msgid="8704986163711455010">"samskipti við stjórnanda tækis"</string>
<string name="permdesc_bindDeviceAdmin" msgid="569715419543907930">"Leyfir handhafa að senda tilgang til stjórnanda tækis. Ætti aldrei að vera nauðsynlegt fyrir venjuleg forrit."</string>
<string name="permlab_bindTvInput" msgid="5601264742478168987">"bindast sjónvarpsinntaki"</string>
@@ -742,6 +742,8 @@
<string name="permdesc_bindNotificationListenerService" msgid="985697918576902986">"Leyfir forriti að bindast efsta viðmótslagi hlustunarþjónustu tilkynninga. Ætti aldrei að vera nauðsynlegt fyrir venjuleg forrit."</string>
<string name="permlab_bindConditionProviderService" msgid="1180107672332704641">"bindast þjónustu skilyrðaveitu"</string>
<string name="permdesc_bindConditionProviderService" msgid="1680513931165058425">"Leyfir handhafa að bindast efsta viðmótslagi skilyrðaveitu. Ætti aldrei að vera nauðsynlegt fyrir venjuleg forrit."</string>
+ <string name="permlab_bindMediaRouteService" msgid="6637740382272686835">"bindast beiningarþjónustu fyrir margmiðlun"</string>
+ <string name="permdesc_bindMediaRouteService" msgid="6436655024972496687">"Leyfir handhafa að bindast efsta viðmótslagi beiningarþjónustu fyrir margmiðlun. Ætti aldrei að vera nauðsynlegt fyrir venjuleg forrit."</string>
<string name="permlab_bindDreamService" msgid="4153646965978563462">"bindast skjávaraþjónustu"</string>
<string name="permdesc_bindDreamService" msgid="7325825272223347863">"Leyfir handhafa að bindast efsta viðmótslagi skjávaraþjónustu. Ætti aldrei að vera nauðsynlegt fyrir venjuleg forrit."</string>
<string name="permlab_invokeCarrierSetup" msgid="3699600833975117478">"ræsa grunnstillingarforrit frá símafyrirtæki"</string>
@@ -1283,6 +1285,9 @@
<skip />
<string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"Ekki var hægt að tengjast Wi-Fi"</string>
<string name="wifi_watchdog_network_disabled_detailed" msgid="5548780776418332675">" er með lélegt netsamband."</string>
+ <string name="wifi_connect_alert_title" msgid="8455846016001810172">"Leyfa tengingu?"</string>
+ <string name="wifi_connect_alert_message" msgid="8930084523889618078">"%1$s vill fá að tengjast %2$s"</string>
+ <string name="wifi_connect_default_application" msgid="7143109390475484319">"Forrit"</string>
<string name="wifi_p2p_dialog_title" msgid="97611782659324517">"Wi-Fi Direct"</string>
<string name="wifi_p2p_turnon_message" msgid="2909250942299627244">"Ræsa Wi-Fi Direct. Þetta mun slökkva á Wi-Fi biðlara/aðgangsstað."</string>
<string name="wifi_p2p_failed_message" msgid="3763669677935623084">"Ekki var hægt að ræsa Wi-Fi Direct."</string>
diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml
index f343245..fb81d2e 100644
--- a/core/res/res/values-it/strings.xml
+++ b/core/res/res/values-it/strings.xml
@@ -41,8 +41,6 @@
<string name="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g> secondi"</string>
<string name="durationSecond" msgid="985669622276420331">"<xliff:g id="SECONDS">%1$d</xliff:g> secondo"</string>
<string name="untitled" msgid="4638956954852782576">"<Senza nome>"</string>
- <string name="ellipsis" msgid="7899829516048813237">"…"</string>
- <string name="ellipsis_two_dots" msgid="1228078994866030736">"‥"</string>
<string name="emptyPhoneNumber" msgid="7694063042079676517">"(Nessun numero di telefono)"</string>
<string name="unknownName" msgid="2277556546742746522">"(Sconosciuto)"</string>
<string name="defaultVoiceMailAlphaTag" msgid="2660020990097733077">"Segreteria"</string>
@@ -415,6 +413,8 @@
<string name="permdesc_bindRemoteDisplay" msgid="1261242718727295981">"Consente al titolare di collegarsi all\'interfaccia di primo livello di un display remoto. Non dovrebbe essere mai necessaria per le normali applicazioni."</string>
<string name="permlab_bindRemoteViews" msgid="5697987759897367099">"associazione a un servizio widget"</string>
<string name="permdesc_bindRemoteViews" msgid="4717987810137692572">"Consente l\'associazione all\'interfaccia principale di un servizio widget. Non dovrebbe mai essere necessario per le normali applicazioni."</string>
+ <string name="permlab_bindRouteProvider" msgid="4869394607915096847">"collegamento a un servizio provider di routing"</string>
+ <string name="permdesc_bindRouteProvider" msgid="4703804520859960329">"Consente al titolare di collegarsi a qualsiasi provider di routing registrato. Non dovrebbe mai essere necessario per le normali applicazioni."</string>
<string name="permlab_bindDeviceAdmin" msgid="8704986163711455010">"interazione con un amministratore dispositivo"</string>
<string name="permdesc_bindDeviceAdmin" msgid="569715419543907930">"Consente l\'invio di intent a un amministratore del dispositivo. L\'autorizzazione non dovrebbe mai essere necessaria per le normali applicazioni."</string>
<string name="permlab_bindTvInput" msgid="5601264742478168987">"collegamento a ingresso TV"</string>
@@ -742,6 +742,8 @@
<string name="permdesc_bindNotificationListenerService" msgid="985697918576902986">"Consente al titolare di vincolarsi all\'interfaccia di primo livello di un servizio listener di notifica. Non dovrebbe mai essere necessaria per le normali applicazioni."</string>
<string name="permlab_bindConditionProviderService" msgid="1180107672332704641">"collegamento a un servizio provider di condizioni"</string>
<string name="permdesc_bindConditionProviderService" msgid="1680513931165058425">"Consente al titolare di collegarsi all\'interfaccia di primo livello di un servizio provider di condizioni. Non dovrebbe essere mai necessaria per le normali app."</string>
+ <string name="permlab_bindMediaRouteService" msgid="6637740382272686835">"associa a servizio di routing multimediale"</string>
+ <string name="permdesc_bindMediaRouteService" msgid="6436655024972496687">"Consente di eseguire l\'associazione all\'interfaccia di primo livello di un servizio di routing multimediale. Generalmente non necessario per le normali app."</string>
<string name="permlab_bindDreamService" msgid="4153646965978563462">"associa a servizio dream"</string>
<string name="permdesc_bindDreamService" msgid="7325825272223347863">"Consente all\'utente di associare l\'interfaccia di primo livello di un servizio dream. Questa impostazione non è mai necessaria per le app normali."</string>
<string name="permlab_invokeCarrierSetup" msgid="3699600833975117478">"richiamo dell\'app di configurazione operatore-provider"</string>
@@ -1283,6 +1285,9 @@
<skip />
<string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"Impossibile connettersi alla rete Wi-Fi"</string>
<string name="wifi_watchdog_network_disabled_detailed" msgid="5548780776418332675">" ha una connessione Internet debole."</string>
+ <string name="wifi_connect_alert_title" msgid="8455846016001810172">"Consentire la connessione?"</string>
+ <string name="wifi_connect_alert_message" msgid="8930084523889618078">"%1$s vorrebbe connettersi a %2$s"</string>
+ <string name="wifi_connect_default_application" msgid="7143109390475484319">"Un\'applicazione"</string>
<string name="wifi_p2p_dialog_title" msgid="97611782659324517">"Wi-Fi Direct"</string>
<string name="wifi_p2p_turnon_message" msgid="2909250942299627244">"Avvia Wi-Fi Direct. Verrà disattivato il client/hotspot Wi-Fi."</string>
<string name="wifi_p2p_failed_message" msgid="3763669677935623084">"Avvio di Wi-Fi Direct non riuscito."</string>
@@ -1776,8 +1781,7 @@
<string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Richiedi password prima di sbloccare"</string>
<string name="battery_saver_description" msgid="2510530476513605742">"Per aumentare la durata della batteria, la funzione Risparmio energetico riduce le prestazioni del dispositivo e limita vibrazione e gran parte dei dati in background. App di email, messaggistica e altre app basate sulla sincronizzazione potrebbero non essere aggiornate se non le apri.\n\nIl risparmio energetico si disattiva automaticamente quando il dispositivo è in carica."</string>
<string name="downtime_condition_summary" msgid="8761776337475705749">"Fino al termine del periodo di inattività previsto per le <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
- <!-- no translation found for downtime_condition_line_one (8762708714645352010) -->
- <skip />
+ <string name="downtime_condition_line_one" msgid="8762708714645352010">"Fino al termine del periodo di inattività"</string>
<plurals name="zen_mode_duration_minutes_summary">
<item quantity="one" msgid="3177683545388923234">"Per un minuto (fino alle ore <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
<item quantity="other" msgid="2787867221129368935">"Per %1$d minuti (fino alle ore <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
@@ -1797,8 +1801,6 @@
<string name="zen_mode_until" msgid="7336308492289875088">"Fino alle ore <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
<string name="zen_mode_forever" msgid="4316804956488785559">"Sempre"</string>
<string name="toolbar_collapse_description" msgid="2821479483960330739">"Comprimi"</string>
- <!-- no translation found for zen_mode_next_alarm_summary (5915140424683747372) -->
- <skip />
- <!-- no translation found for zen_mode_next_alarm_line_one (5537042951553420916) -->
- <skip />
+ <string name="zen_mode_next_alarm_summary" msgid="5915140424683747372">"Fino alla prossima sveglia alle ore <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
+ <string name="zen_mode_next_alarm_line_one" msgid="5537042951553420916">"Fino alla prossima sveglia"</string>
</resources>
diff --git a/core/res/res/values-iw/strings.xml b/core/res/res/values-iw/strings.xml
index 6553440..2997ecf 100644
--- a/core/res/res/values-iw/strings.xml
+++ b/core/res/res/values-iw/strings.xml
@@ -41,8 +41,6 @@
<string name="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g> שניות"</string>
<string name="durationSecond" msgid="985669622276420331">"שנייה <xliff:g id="SECONDS">%1$d</xliff:g>"</string>
<string name="untitled" msgid="4638956954852782576">">ללא כותרת<"</string>
- <string name="ellipsis" msgid="7899829516048813237">"..."</string>
- <string name="ellipsis_two_dots" msgid="1228078994866030736">"‥"</string>
<string name="emptyPhoneNumber" msgid="7694063042079676517">"(אין מספר טלפון)"</string>
<string name="unknownName" msgid="2277556546742746522">"(לא ידוע)"</string>
<string name="defaultVoiceMailAlphaTag" msgid="2660020990097733077">"דואר קולי"</string>
@@ -415,6 +413,8 @@
<string name="permdesc_bindRemoteDisplay" msgid="1261242718727295981">"הרשאה זו מאפשרת למשתמש לבצע איגוד לממשק הרמה העליונה של צג רחוק. לעולם אינה אמורה להיות נחוצה לאפליקציות רגילות."</string>
<string name="permlab_bindRemoteViews" msgid="5697987759897367099">"הכפפה לשירות Widget"</string>
<string name="permdesc_bindRemoteViews" msgid="4717987810137692572">"מאפשר למשתמש לבצע איגוד לממשק הרמה העליונה של שירות Widget. הרשאה זו לעולם אינה נחוצה לאפליקציות רגילים."</string>
+ <string name="permlab_bindRouteProvider" msgid="4869394607915096847">"איגוד לשירות של ספק ניתוב"</string>
+ <string name="permdesc_bindRouteProvider" msgid="4703804520859960329">"מאפשרת לבעלים לאגד לספקי ניתוב רשומים. לעולם לא אמורה להיות נחוצה עבור אפליקציות רגילות."</string>
<string name="permlab_bindDeviceAdmin" msgid="8704986163711455010">"קיים אינטראקציה עם מנהל המכשיר"</string>
<string name="permdesc_bindDeviceAdmin" msgid="569715419543907930">"מאפשר למשתמש לשלוח כוונות למנהל התקנים. הרשאה זו לעולם אינה נחוצה לאפליקציות רגילים."</string>
<string name="permlab_bindTvInput" msgid="5601264742478168987">"איגוד לקלט טלוויזיה"</string>
@@ -742,6 +742,8 @@
<string name="permdesc_bindNotificationListenerService" msgid="985697918576902986">"הרשאה זו מאפשרת למשתמש לבצע איגוד לממשק הרמה העליונה של שירות מאזין להתראות. הרשאה זו אף פעם אינה נחוצה לאפליקציות רגילים."</string>
<string name="permlab_bindConditionProviderService" msgid="1180107672332704641">"איגוד לשירות ספק תנאי"</string>
<string name="permdesc_bindConditionProviderService" msgid="1680513931165058425">"מאפשרת לבעלים לאגד לממשק ברמה העליונה של שירות ספק תנאי. לעולם לא אמורה להיות נחוצה עבור אפליקציות רגילות."</string>
+ <string name="permlab_bindMediaRouteService" msgid="6637740382272686835">"איגוד לשירות ניתוב מדיה"</string>
+ <string name="permdesc_bindMediaRouteService" msgid="6436655024972496687">"מאפשרת לבעלים לאגוד לממשק ברמה העליונה של שירות ניתוב מדיה. לעולם לא אמורה להיות נחוצה עבור אפליקציות רגילות."</string>
<string name="permlab_bindDreamService" msgid="4153646965978563462">"איגוד לשירות Dream"</string>
<string name="permdesc_bindDreamService" msgid="7325825272223347863">"מאפשרת לבעלים לבצע איגוד לממשק הרמה העליונה של שירות Dream. הרשאה זו אף פעם אינה נחוצה לאפליקציות רגילות."</string>
<string name="permlab_invokeCarrierSetup" msgid="3699600833975117478">"הפעלה של אפליקציית תצורה שסופקה על ידי ספק"</string>
@@ -1283,6 +1285,9 @@
<skip />
<string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"אין אפשרות להתחבר ל-Wi-Fi"</string>
<string name="wifi_watchdog_network_disabled_detailed" msgid="5548780776418332675">" אינו מחובר היטב לאינטרנט."</string>
+ <string name="wifi_connect_alert_title" msgid="8455846016001810172">"האם להתיר את החיבור?"</string>
+ <string name="wifi_connect_alert_message" msgid="8930084523889618078">"%1$s רוצה להתחבר אל %2$s"</string>
+ <string name="wifi_connect_default_application" msgid="7143109390475484319">"אפליקציה"</string>
<string name="wifi_p2p_dialog_title" msgid="97611782659324517">"Wi-Fi ישיר"</string>
<string name="wifi_p2p_turnon_message" msgid="2909250942299627244">"הפעל Wi-Fi ישיר. פעולה זו תכבה את הנקודה לשיתוף אינטרנט ב-Wi-Fi."</string>
<string name="wifi_p2p_failed_message" msgid="3763669677935623084">"לא ניתן להפעיל Wi-Fi ישיר"</string>
@@ -1776,8 +1781,7 @@
<string name="lock_to_app_unlock_password" msgid="6380979775916974414">"בקש סיסמה לפני ביטול הצמדה"</string>
<string name="battery_saver_description" msgid="2510530476513605742">"כדי לעזור בהארכת חיי הסוללה, תכונת \'חיסכון בסוללה\' מצמצמת את פעילות המכשיר ומגבילה את השימוש ברטט וברוב נתוני הרקע. ייתכן שאימייל, שליחת הודעות ואפליקציות אחרות המסתמכות על סנכרון לא יתעדכנו, אלא אם תפתח אותן.\n\nתכונת \'חיסכון בסוללה\' מופסקת אוטומטית כשהמכשיר מחובר לחשמל."</string>
<string name="downtime_condition_summary" msgid="8761776337475705749">"עד לסיום ההשבתה בשעה <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
- <!-- no translation found for downtime_condition_line_one (8762708714645352010) -->
- <skip />
+ <string name="downtime_condition_line_one" msgid="8762708714645352010">"עד לסיום זמן ההשבתה"</string>
<plurals name="zen_mode_duration_minutes_summary">
<item quantity="one" msgid="3177683545388923234">"למשך דקה אחת (עד <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
<item quantity="other" msgid="2787867221129368935">"למשך %1$d דקות (עד <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
@@ -1797,8 +1801,6 @@
<string name="zen_mode_until" msgid="7336308492289875088">"עד <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
<string name="zen_mode_forever" msgid="4316804956488785559">"ללא הגבלה"</string>
<string name="toolbar_collapse_description" msgid="2821479483960330739">"כווץ"</string>
- <!-- no translation found for zen_mode_next_alarm_summary (5915140424683747372) -->
- <skip />
- <!-- no translation found for zen_mode_next_alarm_line_one (5537042951553420916) -->
- <skip />
+ <string name="zen_mode_next_alarm_summary" msgid="5915140424683747372">"עד ההתראה הבאה ב-<xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
+ <string name="zen_mode_next_alarm_line_one" msgid="5537042951553420916">"עד ההתראה הבאה"</string>
</resources>
diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml
index f766f5e..7cd986f 100644
--- a/core/res/res/values-ja/strings.xml
+++ b/core/res/res/values-ja/strings.xml
@@ -41,8 +41,6 @@
<string name="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g>秒"</string>
<string name="durationSecond" msgid="985669622276420331">"<xliff:g id="SECONDS">%1$d</xliff:g>秒"</string>
<string name="untitled" msgid="4638956954852782576">"<新規>"</string>
- <string name="ellipsis" msgid="7899829516048813237">"..."</string>
- <string name="ellipsis_two_dots" msgid="1228078994866030736">"‥"</string>
<string name="emptyPhoneNumber" msgid="7694063042079676517">"(電話番号なし)"</string>
<string name="unknownName" msgid="2277556546742746522">"(名前)"</string>
<string name="defaultVoiceMailAlphaTag" msgid="2660020990097733077">"ボイスメール"</string>
@@ -415,6 +413,8 @@
<string name="permdesc_bindRemoteDisplay" msgid="1261242718727295981">"リモートディスプレイのトップレベルインターフェースにバインドすることを所有者に許可します。通常のアプリでは不要です。"</string>
<string name="permlab_bindRemoteViews" msgid="5697987759897367099">"ウィジェットサービスにバインド"</string>
<string name="permdesc_bindRemoteViews" msgid="4717987810137692572">"ウィジェットサービスのトップレベルインターフェースにバインドすることを所有者に許可します。通常のアプリでは不要です。"</string>
+ <string name="permlab_bindRouteProvider" msgid="4869394607915096847">"ルートプロバイダサービスへのバインド"</string>
+ <string name="permdesc_bindRouteProvider" msgid="4703804520859960329">"登録済みのルートプロバイダにバインドすることを所有者に許可します。通常のアプリでは不要です。"</string>
<string name="permlab_bindDeviceAdmin" msgid="8704986163711455010">"デバイス管理者との通信"</string>
<string name="permdesc_bindDeviceAdmin" msgid="569715419543907930">"デバイス管理者へのintentの送信を所有者に許可します。通常のアプリでは不要です。"</string>
<string name="permlab_bindTvInput" msgid="5601264742478168987">"テレビの入力へのバインド"</string>
@@ -742,6 +742,8 @@
<string name="permdesc_bindNotificationListenerService" msgid="985697918576902986">"通知リスナーサービスのトップレベルインターフェースにバインドすることを所有者に許可します。通常のアプリでは不要です。"</string>
<string name="permlab_bindConditionProviderService" msgid="1180107672332704641">"コンディションプロバイダサービスへのバインド"</string>
<string name="permdesc_bindConditionProviderService" msgid="1680513931165058425">"コンディションプロバイダサービスのトップレベルインターフェースにバインドすることを所有者に許可します。通常のアプリでは不要です。"</string>
+ <string name="permlab_bindMediaRouteService" msgid="6637740382272686835">"メディアルートサービスへのバインド"</string>
+ <string name="permdesc_bindMediaRouteService" msgid="6436655024972496687">"メディアルートサービスのトップレベルインターフェースにバインドすることを所有者に許可します。通常のアプリでは不要です。"</string>
<string name="permlab_bindDreamService" msgid="4153646965978563462">"ドリームサービスにバインド"</string>
<string name="permdesc_bindDreamService" msgid="7325825272223347863">"ドリームサービスのトップレベルインターフェースにバインドすることを所有者に許可します。通常のアプリでは不要です。"</string>
<string name="permlab_invokeCarrierSetup" msgid="3699600833975117478">"携帯通信会社が提供する設定アプリの呼び出し"</string>
@@ -1283,6 +1285,9 @@
<skip />
<string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"Wi-Fiに接続できませんでした"</string>
<string name="wifi_watchdog_network_disabled_detailed" msgid="5548780776418332675">" はインターネット接続に問題があります。"</string>
+ <string name="wifi_connect_alert_title" msgid="8455846016001810172">"接続を許可しますか?"</string>
+ <string name="wifi_connect_alert_message" msgid="8930084523889618078">"%1$sさんが「%2$s」への接続を希望しています"</string>
+ <string name="wifi_connect_default_application" msgid="7143109390475484319">"アプリ"</string>
<string name="wifi_p2p_dialog_title" msgid="97611782659324517">"Wi-Fi Direct"</string>
<string name="wifi_p2p_turnon_message" msgid="2909250942299627244">"Wi-Fi Directを開始します。これによりWi-Fiクライアント/アクセスポイントがOFFになります。"</string>
<string name="wifi_p2p_failed_message" msgid="3763669677935623084">"Wi-Fi Directを開始できませんでした。"</string>
@@ -1776,8 +1781,7 @@
<string name="lock_to_app_unlock_password" msgid="6380979775916974414">"オフライン再生を解除する前にパスワードの入力を求める"</string>
<string name="battery_saver_description" msgid="2510530476513605742">"バッテリーを長持ちさせるため、バッテリーセーバーは端末のパフォーマンス、バイブレーション、ほとんどのバックグラウンドデータを制限します。同期を使用するメールやメッセージなどのアプリは起動しないと更新されない場合があります。\n\nバッテリーセーバーは、端末の充電中は自動的にOFFになります。"</string>
<string name="downtime_condition_summary" msgid="8761776337475705749">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g>にダウンロードが終わるまで"</string>
- <!-- no translation found for downtime_condition_line_one (8762708714645352010) -->
- <skip />
+ <string name="downtime_condition_line_one" msgid="8762708714645352010">"ダウンタイム終了まで"</string>
<plurals name="zen_mode_duration_minutes_summary">
<item quantity="one" msgid="3177683545388923234">"1分間(<xliff:g id="FORMATTEDTIME">%2$s</xliff:g>まで)"</item>
<item quantity="other" msgid="2787867221129368935">"%1$d分間(<xliff:g id="FORMATTEDTIME">%2$s</xliff:g>まで)"</item>
@@ -1797,8 +1801,6 @@
<string name="zen_mode_until" msgid="7336308492289875088">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g>まで"</string>
<string name="zen_mode_forever" msgid="4316804956488785559">"制限なし"</string>
<string name="toolbar_collapse_description" msgid="2821479483960330739">"折りたたむ"</string>
- <!-- no translation found for zen_mode_next_alarm_summary (5915140424683747372) -->
- <skip />
- <!-- no translation found for zen_mode_next_alarm_line_one (5537042951553420916) -->
- <skip />
+ <string name="zen_mode_next_alarm_summary" msgid="5915140424683747372">"次のアラーム(<xliff:g id="FORMATTEDTIME">%1$s</xliff:g>)まで"</string>
+ <string name="zen_mode_next_alarm_line_one" msgid="5537042951553420916">"次のアラームまで"</string>
</resources>
diff --git a/core/res/res/values-ka-rGE/strings.xml b/core/res/res/values-ka-rGE/strings.xml
index 883a949..fe60520 100644
--- a/core/res/res/values-ka-rGE/strings.xml
+++ b/core/res/res/values-ka-rGE/strings.xml
@@ -41,8 +41,6 @@
<string name="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g> წმ"</string>
<string name="durationSecond" msgid="985669622276420331">"<xliff:g id="SECONDS">%1$d</xliff:g> წმ"</string>
<string name="untitled" msgid="4638956954852782576">"უსათაურო"</string>
- <string name="ellipsis" msgid="7899829516048813237">"…"</string>
- <string name="ellipsis_two_dots" msgid="1228078994866030736">"‥"</string>
<string name="emptyPhoneNumber" msgid="7694063042079676517">"(ტელეფონის ნომრის გარეშე)"</string>
<string name="unknownName" msgid="2277556546742746522">"(უცნობი)"</string>
<string name="defaultVoiceMailAlphaTag" msgid="2660020990097733077">"ხმოვანი ფოსტა"</string>
@@ -415,6 +413,8 @@
<string name="permdesc_bindRemoteDisplay" msgid="1261242718727295981">"მფლობელს შეეძლება მიებას დისტანციურ მონიტორის ზედა დონის ინტერფეისს. ჩვეულებრივ აპს ეს წესით არასოდეს უნდა დაჭირდეს."</string>
<string name="permlab_bindRemoteViews" msgid="5697987759897367099">"ვიჯეტ სერვისთან დაკავშირება"</string>
<string name="permdesc_bindRemoteViews" msgid="4717987810137692572">"აპს შეეძლება ზედა დონის ინტერფეისის ვიჯეტთან დაკავშირება. არასდროს გამოიყენება ჩვეულებრივ აპებში."</string>
+ <string name="permlab_bindRouteProvider" msgid="4869394607915096847">"მარშრუტის სერვისის პროვაიდერთან შეკავშირება"</string>
+ <string name="permdesc_bindRouteProvider" msgid="4703804520859960329">"საშუალებას აძლევს მფლობელს შეკავშირდეს მარშრუტების ნებისმიერ პროვაიდერთან. ჩვეულებრივ აპებს უმეტეს შემთხვევაში არ დაჭირდება."</string>
<string name="permlab_bindDeviceAdmin" msgid="8704986163711455010">"მოწყობილობის ადმინთან ინტერაქცია"</string>
<string name="permdesc_bindDeviceAdmin" msgid="569715419543907930">"აპს შეეძლება მოწყობილობის ადმინისტრატორისთვის intent ობიექტების გაგზავნა. არასდროს გამოიყენება ჩვეულებრივ აპებში."</string>
<string name="permlab_bindTvInput" msgid="5601264742478168987">"TV შეყვანასთან მიბმა"</string>
@@ -742,6 +742,8 @@
<string name="permdesc_bindNotificationListenerService" msgid="985697918576902986">"მფლობელს შეეძლება შეტყობინებების მსმენლის სერვისის ზედა დონის ინტერფეისთან დაკავშირება. არ უნდა მოხდეს მისი გამოყენება ჩვეუელებრივი აპებისთვის.ფ"</string>
<string name="permlab_bindConditionProviderService" msgid="1180107672332704641">"მდგომარეობის პროვაიდერის სერვისებთან შეკავშირება"</string>
<string name="permdesc_bindConditionProviderService" msgid="1680513931165058425">"მფლობელს შეეძლება შეკავშირდეს მდგომარეობის პროვაიდერის სერვისების ზედა დონის ინტერფეისთან. ჩვეულებრივ აპს ეს წესით არასოდეს უნდა დასჭირდეს."</string>
+ <string name="permlab_bindMediaRouteService" msgid="6637740382272686835">"მედიის მარშრუტის სერვისთან შეკავშირება"</string>
+ <string name="permdesc_bindMediaRouteService" msgid="6436655024972496687">"მფლობელს შეეძლება შეკავშირდეს მედიის მარშრუტიზაციის სერვისების ზედა დონის ინტერფეისთან. ჩვეულებრივ აპს ეს წესით არასოდეს უნდა დასჭირდეს."</string>
<string name="permlab_bindDreamService" msgid="4153646965978563462">"dream სერვისთან მიბმა"</string>
<string name="permdesc_bindDreamService" msgid="7325825272223347863">"მფლობელს შეეძლება მიებას dream სერვისის ზედა დონის ინტერფეისი. ჩვეულებრივ აპს ეს წესით არასოდეს უნდა დაჭირდეს."</string>
<string name="permlab_invokeCarrierSetup" msgid="3699600833975117478">"ოპერატორის მიერ მოწოდებული კოფიგურაციის აპის გამოხმობა"</string>
@@ -1283,6 +1285,9 @@
<skip />
<string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"Wi-Fi-თან დაკავშირება ვერ მოხერხდა"</string>
<string name="wifi_watchdog_network_disabled_detailed" msgid="5548780776418332675">" აქვს ცუდი ინტერნეტ კავშირი."</string>
+ <string name="wifi_connect_alert_title" msgid="8455846016001810172">"გსურთ კავშირის დაშვება?"</string>
+ <string name="wifi_connect_alert_message" msgid="8930084523889618078">"%1$s-ს სურს %2$s-თან დაკავშირება"</string>
+ <string name="wifi_connect_default_application" msgid="7143109390475484319">"აპლიკაცია"</string>
<string name="wifi_p2p_dialog_title" msgid="97611782659324517">"Wi-Fi Direct"</string>
<string name="wifi_p2p_turnon_message" msgid="2909250942299627244">"ჩართეთ Wi-Fi Direct. ეს გამოიწვევს Wi-Fi კლიენტისა/უსადენო ქსელის გამორთვას."</string>
<string name="wifi_p2p_failed_message" msgid="3763669677935623084">"ვერ მოხერხდა Wi-Fi Direct-ის გაშვება."</string>
@@ -1776,7 +1781,7 @@
<string name="lock_to_app_unlock_password" msgid="6380979775916974414">"ფიქსაციის მოხსნამდე პაროლის მოთხოვნა"</string>
<string name="battery_saver_description" msgid="2510530476513605742">"ბატარეის გამძლეობის გასახანგრძლივებლად, ბატარეის დამზოგი ამცირებს თქვენი მოწყობილობის წარმადობას და ზღუდავს ვიბრაციასა და უმეტეს ფონურ მონაცემს. თუ არ განაახლებთ, შეიძლება არ გაიხსნას ელფოსტა, შეტყობინებები და სხვა აპები, რომლებიც სინქრონიზაციაზეა დამოკიდებული.\n\nბატარეის დამზოგი ავტომატურად გამოირთვება, როდესაც თქვენი მოწყობილობა იტენება."</string>
<string name="downtime_condition_summary" msgid="8761776337475705749">"დანამ თქვენი კავშირგარეშე დრო დასრულდებოდეს <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>-ზე"</string>
- <string name="downtime_condition_line_one" msgid="8762708714645352010">"სანამ ავარიული პაუზა დასრულდებდეს"</string>
+ <string name="downtime_condition_line_one" msgid="8762708714645352010">"სანამ ავარიული პაუზა დასრულდებოდეს"</string>
<plurals name="zen_mode_duration_minutes_summary">
<item quantity="one" msgid="3177683545388923234">"ერთი წუთის განმავლობაში (<xliff:g id="FORMATTEDTIME">%2$s</xliff:g>-მდე)"</item>
<item quantity="other" msgid="2787867221129368935">"%1$d წუთის განმავლობაში (<xliff:g id="FORMATTEDTIME">%2$s</xliff:g>-მდე)"</item>
diff --git a/core/res/res/values-kk-rKZ/strings.xml b/core/res/res/values-kk-rKZ/strings.xml
index 5a80dc6..bc31d3c 100644
--- a/core/res/res/values-kk-rKZ/strings.xml
+++ b/core/res/res/values-kk-rKZ/strings.xml
@@ -41,8 +41,6 @@
<string name="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g> сек."</string>
<string name="durationSecond" msgid="985669622276420331">"<xliff:g id="SECONDS">%1$d</xliff:g> сек."</string>
<string name="untitled" msgid="4638956954852782576">"<Атаусыз>"</string>
- <string name="ellipsis" msgid="7899829516048813237">"…"</string>
- <string name="ellipsis_two_dots" msgid="1228078994866030736">"‥"</string>
<string name="emptyPhoneNumber" msgid="7694063042079676517">"(Телефон нөмірі жоқ)"</string>
<string name="unknownName" msgid="2277556546742746522">"(Белгісіз)"</string>
<string name="defaultVoiceMailAlphaTag" msgid="2660020990097733077">"Дауыс-хабар"</string>
@@ -415,6 +413,8 @@
<string name="permdesc_bindRemoteDisplay" msgid="1261242718727295981">"Пайдаланушыға қашықтан басқарылатын дисплейдің жоғары деңгейлі интерфейсіне жалғану мүмкіндігін ұсынады. Қалыпты қолданбаны ешқашан қажет етпеуі тиіс."</string>
<string name="permlab_bindRemoteViews" msgid="5697987759897367099">"виджет қызметіне байланыстыру"</string>
<string name="permdesc_bindRemoteViews" msgid="4717987810137692572">"Пайдаланушыға виджет қызметінің жоғары деңгейлі интерфейсіне байластыруға рұқсат береді. Қалыпты қолданбалар үшін ешқашан қажет болмайды."</string>
+ <string name="permlab_bindRouteProvider" msgid="4869394607915096847">"маршрут провайдері қызметіне байластыру"</string>
+ <string name="permdesc_bindRouteProvider" msgid="4703804520859960329">"Пайдаланушыға кез келген тіркелген маршрут провайдерлеріне байластыруға рұқсат береді. Қалыпты қолданбалар үшін ешқашан қажет болмайды."</string>
<string name="permlab_bindDeviceAdmin" msgid="8704986163711455010">"құрал әкімшісімен қатынасу"</string>
<string name="permdesc_bindDeviceAdmin" msgid="569715419543907930">"Иесіне ниеттерді құрылғы әкімшісіне жіберуге рұқсат береді. Қалыпты қолданбалар үшін ешқашан қажет болмайды."</string>
<string name="permlab_bindTvInput" msgid="5601264742478168987">"ТД кірісіне байластыру"</string>
@@ -742,6 +742,8 @@
<string name="permdesc_bindNotificationListenerService" msgid="985697918576902986">"Пайдаланушыға хабар есту қызметінің жоғары деңгейлі интерфейсіне жалғану мүмкіндігін ұсынады. Қалыпты қолданбаны ешқашан қажет етпеуі тиіс."</string>
<string name="permlab_bindConditionProviderService" msgid="1180107672332704641">"шарттар провайдері қызметіне байластыру"</string>
<string name="permdesc_bindConditionProviderService" msgid="1680513931165058425">"Пайдаланушыға шарт провайдері қызметінің жоғары деңгейлі интерфейсіне байластыруға рұқсат береді. Қалыпты қолданбалар үшін ешқашан қажет болмайды."</string>
+ <string name="permlab_bindMediaRouteService" msgid="6637740382272686835">"медианы бағыттау қызметіне байластыру"</string>
+ <string name="permdesc_bindMediaRouteService" msgid="6436655024972496687">"Иесіне медиа бағыттау қызметінің жоғарғы деңгейлі интерфейсіне байластыруға рұқсат етеді. Қалыпты қолданбалар үшін ешқашан қажет болмайды."</string>
<string name="permlab_bindDreamService" msgid="4153646965978563462">"dream қызметіне байластыру"</string>
<string name="permdesc_bindDreamService" msgid="7325825272223347863">"Иесіне dream қызметінің жоғарғы деңгейлі интерфейсіне байластыруға рұқсат береді. Қалыпты қолданбалар үшін ешқашан қажет болмайды."</string>
<string name="permlab_invokeCarrierSetup" msgid="3699600833975117478">"жабдықтаушы ұсынатын жасақтамалық қолданбаны қосу"</string>
@@ -1283,6 +1285,9 @@
<skip />
<string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"Wi-Fi желісіне қосыла алмады"</string>
<string name="wifi_watchdog_network_disabled_detailed" msgid="5548780776418332675">" Интернет байланысы нашар."</string>
+ <string name="wifi_connect_alert_title" msgid="8455846016001810172">"Қосылуға рұқсат ету керек пе?"</string>
+ <string name="wifi_connect_alert_message" msgid="8930084523889618078">"%1$s %2$s қосылғысы келеді"</string>
+ <string name="wifi_connect_default_application" msgid="7143109390475484319">"Қолданба"</string>
<string name="wifi_p2p_dialog_title" msgid="97611782659324517">"Wi-Fi тікелей"</string>
<string name="wifi_p2p_turnon_message" msgid="2909250942299627244">"Wi-Fi Тікелей байланысын бастау. Бұл Wi-Fi клиент/хот-спотты өшіреді."</string>
<string name="wifi_p2p_failed_message" msgid="3763669677935623084">"Wi-Fi Тікелей байланысын қоса алмады."</string>
@@ -1776,8 +1781,7 @@
<string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Босату алдында құпия сөзді сұрау"</string>
<string name="battery_saver_description" msgid="2510530476513605742">"Батареяның қызмет мерзімін жақсарту үшін батарея үнемдегіш құрылғының өнімділігін азайтады және діріл мен фондық деректердің көпшілігін шектейді. Синхрондауды қажет ететін электрондық пошта, хабар алмасу және басқа қолданбалар ашқанша жаңартылмауы мүмкін.\n\nБатарея үнемдегіш құрылғы зарядталып жатқанда автоматты түрде өшеді."</string>
<string name="downtime_condition_summary" msgid="8761776337475705749">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g> уақытында әрекетсіздік аяқталғанша"</string>
- <!-- no translation found for downtime_condition_line_one (8762708714645352010) -->
- <skip />
+ <string name="downtime_condition_line_one" msgid="8762708714645352010">"Бос тұру уақыты аяқталғанша"</string>
<plurals name="zen_mode_duration_minutes_summary">
<item quantity="one" msgid="3177683545388923234">"Бір минут бойы (<xliff:g id="FORMATTEDTIME">%2$s</xliff:g> дейін)"</item>
<item quantity="other" msgid="2787867221129368935">"%1$d минут бойы (<xliff:g id="FORMATTEDTIME">%2$s</xliff:g> дейін)"</item>
@@ -1797,8 +1801,6 @@
<string name="zen_mode_until" msgid="7336308492289875088">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g> дейін"</string>
<string name="zen_mode_forever" msgid="4316804956488785559">"Белгісіз уақыт бойы"</string>
<string name="toolbar_collapse_description" msgid="2821479483960330739">"Тасалау"</string>
- <!-- no translation found for zen_mode_next_alarm_summary (5915140424683747372) -->
- <skip />
- <!-- no translation found for zen_mode_next_alarm_line_one (5537042951553420916) -->
- <skip />
+ <string name="zen_mode_next_alarm_summary" msgid="5915140424683747372">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g> уақытындағы келесі дабылға дейін"</string>
+ <string name="zen_mode_next_alarm_line_one" msgid="5537042951553420916">"Келесі дабылға дейін"</string>
</resources>
diff --git a/core/res/res/values-km-rKH/strings.xml b/core/res/res/values-km-rKH/strings.xml
index 7c98e2f..26f4438 100644
--- a/core/res/res/values-km-rKH/strings.xml
+++ b/core/res/res/values-km-rKH/strings.xml
@@ -40,8 +40,6 @@
<string name="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g> វិនាទី"</string>
<string name="durationSecond" msgid="985669622276420331">"<xliff:g id="SECONDS">%1$d</xliff:g> វិនាទី"</string>
<string name="untitled" msgid="4638956954852782576">"<គ្មានចំណងជើង>"</string>
- <string name="ellipsis" msgid="7899829516048813237">"…"</string>
- <string name="ellipsis_two_dots" msgid="1228078994866030736">"‥"</string>
<string name="emptyPhoneNumber" msgid="7694063042079676517">"(គ្មានលេខទូរស័ព្ទ)"</string>
<string name="unknownName" msgid="2277556546742746522">"(មិនស្គាល់)"</string>
<string name="defaultVoiceMailAlphaTag" msgid="2660020990097733077">"សារជាសំឡេង"</string>
@@ -414,6 +412,8 @@
<string name="permdesc_bindRemoteDisplay" msgid="1261242718727295981">"អនុញ្ញាតឲ្យម្ចាស់ភ្ជាប់ទៅចំណុចប្រទាក់កម្រិតកំពូលនៃការបង្ហាញពីចម្ងាយ។ មិនគួរចាំបាច់សម្រាប់កម្មវិធីធម្មតាទេ។"</string>
<string name="permlab_bindRemoteViews" msgid="5697987759897367099">"ចងសេវាកម្មធាតុក្រាហ្វិក"</string>
<string name="permdesc_bindRemoteViews" msgid="4717987810137692572">"ឲ្យម្ចាស់ចងចំណុចប្រទាក់កម្រិតកំពូលនៃសេវាកម្មធាតុក្រាហ្វិក។ មិនគួរចាំបាច់សម្រាប់កម្មវិធីធម្មតាទេ។"</string>
+ <string name="permlab_bindRouteProvider" msgid="4869394607915096847">"ភ្ជាប់ទៅសេវាកម្មក្រុមហ៊ុនផ្ដល់ច្រក"</string>
+ <string name="permdesc_bindRouteProvider" msgid="4703804520859960329">"អនុញ្ញាតឲ្យម្ចាស់ភ្ជាប់ទៅក្រុមហ៊ុនផ្ដល់ច្រកដែលបានចុះឈ្មោះ។ មិនគួរចាំបាច់សម្រាប់កម្មវិធីធម្មតាទេ។"</string>
<string name="permlab_bindDeviceAdmin" msgid="8704986163711455010">"ទាក់ទងជាមួយអ្នកគ្រប់គ្រងឧបករណ៍"</string>
<string name="permdesc_bindDeviceAdmin" msgid="569715419543907930">"ឲ្យម្ចាស់ផ្ញើគោលបំណងទៅអ្នកគ្រប់គ្រងឧបករណ៍។ មិនគួរចាំបាច់សម្រាប់កម្មវិធីធម្មតាទេ។"</string>
<string name="permlab_bindTvInput" msgid="5601264742478168987">"ភ្ជាប់ទៅការបញ្ចូលទូរទស្សន៍"</string>
@@ -741,6 +741,8 @@
<string name="permdesc_bindNotificationListenerService" msgid="985697918576902986">"ឲ្យម្ចាស់ចងចំណុចប្រទាក់កម្រិតកំពូលនៃសេវាកម្មកម្មវិធីស្ដាប់ការជូនដំណឹង។ មិនគួរចាំបាច់សម្រាប់កម្មវិធីធម្មតាទេ។"</string>
<string name="permlab_bindConditionProviderService" msgid="1180107672332704641">"ភ្ជាប់ទៅសេវាកម្មក្រុមហ៊ុនផ្ដល់លក្ខខណ្ឌ"</string>
<string name="permdesc_bindConditionProviderService" msgid="1680513931165058425">"អនុញ្ញាតឲ្យម្ចាស់ភ្ជាប់ទៅចំណុចប្រទាក់កម្រិតកំពូលរបស់សេវាកម្មក្រុមហ៊ុនផ្ដល់លក្ខខណ្ឌ។ មិនគួរចាំបាច់សម្រាប់កម្មវិធីធម្មតាទេ។"</string>
+ <string name="permlab_bindMediaRouteService" msgid="6637740382272686835">"ភ្ជាប់ទៅសេវាផ្លូវមេឌៀ"</string>
+ <string name="permdesc_bindMediaRouteService" msgid="6436655024972496687">"អនុញ្ញាតឲ្យម្ចាស់ភ្ជាប់ទៅចំណុចប្រទាក់ពេញនិយមនៃសេវាកម្មផ្លូវមេឌៀ។ មិនគួរចាំបាច់សម្រាប់កម្មវិធីធម្មតាទេ។"</string>
<string name="permlab_bindDreamService" msgid="4153646965978563462">"ភ្ជាប់ទៅសេវាកម្មស្រមោលស្រមៃ"</string>
<string name="permdesc_bindDreamService" msgid="7325825272223347863">"អនុញ្ញាតឲ្យម្ចាស់ភ្ជាប់ទៅចំណុចប្រទាក់កម្រិតកំពូលនៃសេវាកម្មស្រមើស្រមៃ។ មិនគួរចាំបាច់សម្រាប់កម្មវិធីធម្មតាទេ។"</string>
<string name="permlab_invokeCarrierSetup" msgid="3699600833975117478">"ដកហូតកម្មវិធីកំណត់រចនាសម្ព័ន្ធដែលបានផ្ដល់ដោយក្រុមហ៊ុនបញ្ជូន"</string>
@@ -1284,6 +1286,9 @@
<skip />
<string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"មិនអាចតភ្ជាប់វ៉ាយហ្វាយ"</string>
<string name="wifi_watchdog_network_disabled_detailed" msgid="5548780776418332675">" មានការតភ្ជាប់អ៊ីនធឺណិតមិនល្អ។"</string>
+ <string name="wifi_connect_alert_title" msgid="8455846016001810172">"អនុញ្ញាតភ្ជាប់?"</string>
+ <string name="wifi_connect_alert_message" msgid="8930084523889618078">"%1$s ចង់ភ្ជាប់ %2$s"</string>
+ <string name="wifi_connect_default_application" msgid="7143109390475484319">"កម្មវិធី"</string>
<string name="wifi_p2p_dialog_title" msgid="97611782659324517">"វ៉ាយហ្វាយផ្ទាល់"</string>
<string name="wifi_p2p_turnon_message" msgid="2909250942299627244">"ចាប់ផ្ដើមវ៉ាយហ្វាយផ្ទាល់។ វានឹងបិទវ៉ាយហ្វាយហតស្ពត។"</string>
<string name="wifi_p2p_failed_message" msgid="3763669677935623084">"មិនអាចចាប់ផ្ដើមវ៉ាយហ្វាដោយផ្ទាល់។"</string>
diff --git a/core/res/res/values-kn-rIN/strings.xml b/core/res/res/values-kn-rIN/strings.xml
index ba4817d..8915742 100644
--- a/core/res/res/values-kn-rIN/strings.xml
+++ b/core/res/res/values-kn-rIN/strings.xml
@@ -41,8 +41,6 @@
<string name="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g> ಸೆಕೆಂಡುಗಳು"</string>
<string name="durationSecond" msgid="985669622276420331">"<xliff:g id="SECONDS">%1$d</xliff:g> ಸೆಕೆಂಡುಗಳು"</string>
<string name="untitled" msgid="4638956954852782576">"<ಶೀರ್ಷಿಕೆ ರಹಿತ>"</string>
- <string name="ellipsis" msgid="7899829516048813237">"…"</string>
- <string name="ellipsis_two_dots" msgid="1228078994866030736">"‥"</string>
<string name="emptyPhoneNumber" msgid="7694063042079676517">"(ಯಾವುದೇ ಫೋನ್ ಸಂಖ್ಯೆಯಿಲ್ಲ)"</string>
<string name="unknownName" msgid="2277556546742746522">"(ಅಜ್ಞಾತ)"</string>
<string name="defaultVoiceMailAlphaTag" msgid="2660020990097733077">"ಧ್ವನಿಮೇಲ್"</string>
@@ -415,6 +413,8 @@
<string name="permdesc_bindRemoteDisplay" msgid="1261242718727295981">"ರಿಮೋಟ್ ಪ್ರದರ್ಶನದ ಮೇಲ್ಮಟ್ಟದ ಇಂಟರ್ಫೇಸ್ಗೆ ಪ್ರತಿಬಂಧಿಸಲು ಹೊಂದಿರುವವರಿಗೆ ಅವಕಾಶ ಮಾಡಿಕೊಡುತ್ತದೆ. ಸಾಮಾನ್ಯ ಅಪ್ಲಿಕೇಶನ್ಗಳಿಗಾಗಿ ಎಂದಿಗೂ ಅಗತ್ಯವಿರುವುದಿಲ್ಲ."</string>
<string name="permlab_bindRemoteViews" msgid="5697987759897367099">"ವಿಜೆಟ್ ಸೇವೆಗೆ ಪ್ರತಿಬಂಧಿಸಿ"</string>
<string name="permdesc_bindRemoteViews" msgid="4717987810137692572">"ವಿಜೆಟ್ ಸೇವೆಯ ಮೇಲ್ಮಟ್ಟದ ಇಂಟರ್ಫೇಸ್ಗೆ ಪ್ರತಿಬಂಧಿಸಲು ಹೊಂದಿರುವವರಿಗೆ ಅವಕಾಶ ನೀಡುತ್ತದೆ. ಸಾಮಾನ್ಯ ಅಪ್ಲಿಕೇಶನ್ಗಳಿಗೆ ಎಂದಿಗೂ ಅಗತ್ಯವಿರುವುದಿಲ್ಲ."</string>
+ <string name="permlab_bindRouteProvider" msgid="4869394607915096847">"ಮಾರ್ಗ ಪೂರೈಕೆದಾರರ ಸೇವೆಯನ್ನು ಪ್ರತಿಬಂಧಿಸು"</string>
+ <string name="permdesc_bindRouteProvider" msgid="4703804520859960329">"ಯಾವುದೇ ನೋಂದಾಯಿತ ಪೂರೈಕೆದಾರರನ್ನು ಪ್ರತಿಬಂಧಿಸಲು ಹೊಂದಿರುವವರಿಗೆ ಅವಕಾಶ ಮಾಡಿಕೊಡುತ್ತದೆ. ಸಾಮಾನ್ಯ ಅಪ್ಲಿಕೇಶನ್ಗಳಿಗೆ ಎಂದಿಗೂ ಅಗತ್ಯವಿರುವುದಿಲ್ಲ."</string>
<string name="permlab_bindDeviceAdmin" msgid="8704986163711455010">"ಸಾಧನ ನಿರ್ವಾಹಕರ ಜೊತೆಗೆ ಸಂವಹನ ನಡೆಸಿ"</string>
<string name="permdesc_bindDeviceAdmin" msgid="569715419543907930">"ಸಾಧನ ನಿರ್ವಾಹಕರಿಗೆ ಉದ್ದೇಶಗಳನ್ನು ಕಳುಹಿಸಲು ಹೊಂದಿರುವವರಿಗೆ ಅವಕಾಶ ಮಾಡಿಕೊಡುತ್ತದೆ. ಸಾಮಾನ್ಯ ಅಪ್ಲಿಕೇಶನ್ಗಳಿಗಾಗಿ ಎಂದಿಗೂ ಅಗತ್ಯವಿರುವುದಿಲ್ಲ."</string>
<string name="permlab_bindTvInput" msgid="5601264742478168987">"TV ಇನ್ಪುಟ್ ಅನ್ನು ಪ್ರತಿಬಂಧಿಸು"</string>
@@ -742,6 +742,8 @@
<string name="permdesc_bindNotificationListenerService" msgid="985697918576902986">"ಅಧಿಸೂಚನೆ ಕೇಳುಗ ಸೇವೆಯ ಮೇಲ್ಮಟ್ಟದ ಇಂಟರ್ಫೇಸ್ಗೆ ಪ್ರತಿಬಂಧಿಸಲು ಹೊಂದಿರುವವರಿಗೆ ಅವಕಾಶ ಮಾಡಿಕೊಡುತ್ತದೆ. ಸಾಮಾನ್ಯ ಅಪ್ಲಿಕೇಶನ್ಗಳಿಗೆ ಎಂದಿಗೂ ಅಗತ್ಯವಿರುವುದಿಲ್ಲ."</string>
<string name="permlab_bindConditionProviderService" msgid="1180107672332704641">"ಕಂಡೀಶನ್ ಪೂರೈಕೆದಾರರ ಸೇವೆಯನ್ನು ಪ್ರತಿಬಂಧಿಸು"</string>
<string name="permdesc_bindConditionProviderService" msgid="1680513931165058425">"ಕಂಡೀಶನ್ ಪೂರೈಕೆದಾರರ ಮೇಲ್ಮಟ್ಟದ ಇಂಟರ್ಫೇಸ್ಗೆ ಪ್ರತಿಬಂಧಿಸಲು ಹೊಂದಿರುವವರಿಗೆ ಅವಕಾಶ ಮಾಡಿಕೊಡುತ್ತದೆ. ಸಾಮಾನ್ಯ ಅಪ್ಲಿಕೇಶನ್ಗಳಿಗೆ ಎಂದಿಗೂ ಅಗತ್ಯವಿರುವುದಿಲ್ಲ."</string>
+ <string name="permlab_bindMediaRouteService" msgid="6637740382272686835">"ಮಾಧ್ಯಮ ಮಾರ್ಗ ಸೇವೆಯನ್ನು ಪ್ರತಿಬಂಧಿಸು"</string>
+ <string name="permdesc_bindMediaRouteService" msgid="6436655024972496687">"ಮಾಧ್ಯಮ ವರ್ಗ ಸೇವೆಯ ಮೇಲ್ಮಟ್ಟದ ಇಂಟರ್ಫೇಸ್ಗೆ ಪ್ರತಿಬಂಧಿಸಲು ಹೊಂದಿರುವವರಿಗೆ ಅವಕಾಶ ಮಾಡಿಕೊಡುತ್ತದೆ. ಸಾಮಾನ್ಯ ಅಪ್ಲಿಕೇಶನ್ಗಳಿಗೆ ಎಂದಿಗೂ ಅಗತ್ಯವಿರುವುದಿಲ್ಲ."</string>
<string name="permlab_bindDreamService" msgid="4153646965978563462">"ಕನಸಿನ ಸೇವೆಗೆ ಪ್ರತಿಬಂಧಿಸಿ"</string>
<string name="permdesc_bindDreamService" msgid="7325825272223347863">"ಕನಸಿನ ಸೇವೆಯ ಮೇಲ್ಮಟ್ಟದ ಇಂಟರ್ಫೇಸ್ಗೆ ಪ್ರತಿಬಂಧಿಸಲು ಮಾಲೀಕರಿಗೆ ಅವಕಾಶ ನೀಡುತ್ತದೆ. ಸಾಮಾನ್ಯ ಅಪ್ಲಿಕೇಶನ್ಗಳಿಗೆ ಎಂದಿಗೂ ಅಗತ್ಯವಿರುವುದಿಲ್ಲ."</string>
<string name="permlab_invokeCarrierSetup" msgid="3699600833975117478">"ವಾಹಕ-ಒದಗಿಸಿರುವ ಕಾನ್ಫಿಗರೇಶನ್ ಅಪ್ಲಿಕೇಶನ್ಗೆ ವಿನಂತಿಸಿಕೊಳ್ಳಿ"</string>
@@ -1283,6 +1285,9 @@
<skip />
<string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"Wi-Fi ಗೆ ಸಂಪರ್ಕಿಸಲು ಸಾಧ್ಯವಾಗುತ್ತಿಲ್ಲ"</string>
<string name="wifi_watchdog_network_disabled_detailed" msgid="5548780776418332675">" ಕಳಪೆ ಇಂಟರ್ನೆಟ್ ಸಂಪರ್ಕವನ್ನು ಹೊಂದಿದೆ."</string>
+ <string name="wifi_connect_alert_title" msgid="8455846016001810172">"ಸಂಪರ್ಕವನ್ನು ಅನುಮತಿಸುವುದೇ?"</string>
+ <string name="wifi_connect_alert_message" msgid="8930084523889618078">"%1$s ಅವರು %2$s ಗೆ ಸಂಪರ್ಕಿಸಲು ಬಯಸುತ್ತಾರೆ"</string>
+ <string name="wifi_connect_default_application" msgid="7143109390475484319">"ಅಪ್ಲಿಕೇಶನ್"</string>
<string name="wifi_p2p_dialog_title" msgid="97611782659324517">"Wi-Fi ಡೈರೆಕ್ಟ್"</string>
<string name="wifi_p2p_turnon_message" msgid="2909250942299627244">"Wi-Fi ಡೈರೆಕ್ಟ್ ಪ್ರಾರಂಭಿಸಿ. ಇದು Wi-Fi ಕ್ಲೈಂಟ್/ಹಾಟ್ಸ್ಪಾಟ್ ಅನ್ನು ಆಫ್ ಮಾಡುತ್ತದೆ."</string>
<string name="wifi_p2p_failed_message" msgid="3763669677935623084">"Wi-Fi ಡೈರೆಕ್ಟ್ ಪ್ರಾರಂಭಿಸಲು ಸಾಧ್ಯವಾಗುತ್ತಿಲ್ಲ."</string>
@@ -1776,8 +1781,7 @@
<string name="lock_to_app_unlock_password" msgid="6380979775916974414">"ಅನ್ಪಿನ್ ಮಾಡುವುದಕ್ಕೂ ಮೊದಲು ಪಾಸ್ವರ್ಡ್ ಕೇಳಿ"</string>
<string name="battery_saver_description" msgid="2510530476513605742">"ಬ್ಯಾಟರಿ ಬಾಳಿಕೆಯನ್ನು ಹೆಚ್ಚಿಸುವ ನಿಟ್ಟಿನಲ್ಲಿ ಸಹಾಯ ಮಾಡಲು, ಬ್ಯಾಟರಿ ಉಳಿತಾಯವು ನಿಮ್ಮ ಸಾಧನದ ಕಾರ್ಯಕ್ಷಮತೆಯನ್ನು ಕುಂಠಿತಗೊಳಿಸುತ್ತದೆ ಮತ್ತು ವೈಬ್ರೇಷನ್ ಹಾಗೂ ಹೆಚ್ಚಿನ ಹಿನ್ನೆಲೆ ಡೇಟಾವನ್ನು ಸೀಮಿತಗೊಳಿಸುತ್ತದೆ. ಇಮೇಲ್, ಸಂದೇಶ ಕಳುಹಿಸುವಿಕೆ, ಮತ್ತು ಸಿಂಕ್ ಮಾಡುವುದನ್ನು ಅವಲಂಬಿಸಿರುವ ಇತರ ಅಪ್ಲಿಕೇಶನ್ಗಳನ್ನು ನೀವು ತೆರೆಯುವವರೆಗೆ ಅವುಗಳನ್ನು ನವೀಕರಿಸಲಾಗುವುದಿಲ್ಲ.\n\nನಿಮ್ಮ ಸಾಧನವು ಚಾರ್ಜ್ ಆಗುತ್ತಿರುವಾಗ ಬ್ಯಾಟರಿ ಉಳಿತಾಯವು ಸ್ವಯಂಚಾಲಿತವಾಗಿ ಆಫ್ ಆಗುತ್ತದೆ."</string>
<string name="downtime_condition_summary" msgid="8761776337475705749">"ನಿಮ್ಮ ಅಲಭ್ಯತೆ ಕೊನೆಗೊಳ್ಳುವವರೆಗೆ <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
- <!-- no translation found for downtime_condition_line_one (8762708714645352010) -->
- <skip />
+ <string name="downtime_condition_line_one" msgid="8762708714645352010">"ನಿಮ್ಮ ಸ್ಥಗಿತಕಾಲ ಕೊನೆಗೊಳ್ಳುವವರೆಗೆ"</string>
<plurals name="zen_mode_duration_minutes_summary">
<item quantity="one" msgid="3177683545388923234">"ಒಂದು ನಿಮಿಷದವರೆಗೆ (<xliff:g id="FORMATTEDTIME">%2$s</xliff:g> ವರೆಗೆ)"</item>
<item quantity="other" msgid="2787867221129368935">"%1$d ನಿಮಿಷಗಳವರೆಗೆ (<xliff:g id="FORMATTEDTIME">%2$s</xliff:g> ವರೆಗೆ)"</item>
@@ -1797,8 +1801,6 @@
<string name="zen_mode_until" msgid="7336308492289875088">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g> ವರೆಗೆ"</string>
<string name="zen_mode_forever" msgid="4316804956488785559">"ಅನಿರ್ದಿಷ್ಟವಾಗಿ"</string>
<string name="toolbar_collapse_description" msgid="2821479483960330739">"ಸಂಕುಚಿಸು"</string>
- <!-- no translation found for zen_mode_next_alarm_summary (5915140424683747372) -->
- <skip />
- <!-- no translation found for zen_mode_next_alarm_line_one (5537042951553420916) -->
- <skip />
+ <string name="zen_mode_next_alarm_summary" msgid="5915140424683747372">"ಮುಂದಿನ ಅಲಾರಮ್ <xliff:g id="FORMATTEDTIME">%1$s</xliff:g> ವರೆಗೆ"</string>
+ <string name="zen_mode_next_alarm_line_one" msgid="5537042951553420916">"ಮುಂದಿನ ಅಲಾರಮ್ವರೆಗೆ"</string>
</resources>
diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml
index b67ff6e..f5cc432 100644
--- a/core/res/res/values-ko/strings.xml
+++ b/core/res/res/values-ko/strings.xml
@@ -41,8 +41,6 @@
<string name="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g>초"</string>
<string name="durationSecond" msgid="985669622276420331">"<xliff:g id="SECONDS">%1$d</xliff:g>초"</string>
<string name="untitled" msgid="4638956954852782576">"<제목 없음>"</string>
- <string name="ellipsis" msgid="7899829516048813237">"…"</string>
- <string name="ellipsis_two_dots" msgid="1228078994866030736">"‥"</string>
<string name="emptyPhoneNumber" msgid="7694063042079676517">"(전화번호 없음)"</string>
<string name="unknownName" msgid="2277556546742746522">"(알 수 없음)"</string>
<string name="defaultVoiceMailAlphaTag" msgid="2660020990097733077">"음성메일"</string>
@@ -415,6 +413,8 @@
<string name="permdesc_bindRemoteDisplay" msgid="1261242718727295981">"권한을 가진 프로그램이 원격 디스플레이에 대한 최상위 인터페이스를 사용하도록 허용합니다. 일반 앱에는 필요하지 않습니다."</string>
<string name="permlab_bindRemoteViews" msgid="5697987759897367099">"위젯 서비스와 연결"</string>
<string name="permdesc_bindRemoteViews" msgid="4717987810137692572">"권한을 가진 프로그램이 위젯 서비스에 대한 최상위 인터페이스를 사용하도록 허용합니다. 일반 앱에는 필요하지 않습니다."</string>
+ <string name="permlab_bindRouteProvider" msgid="4869394607915096847">"경로 제공업체 서비스 사용"</string>
+ <string name="permdesc_bindRouteProvider" msgid="4703804520859960329">"권한을 가진 프로그램이 등록된 경로 제공업체를 사용하도록 허용합니다. 일반 앱에는 필요하지 않습니다."</string>
<string name="permlab_bindDeviceAdmin" msgid="8704986163711455010">"기기 관리자와 상호 작용"</string>
<string name="permdesc_bindDeviceAdmin" msgid="569715419543907930">"권한을 가진 프로그램이 기기 관리자에게 인텐트를 보낼 수 있도록 허용합니다. 일반 앱에는 필요하지 않습니다."</string>
<string name="permlab_bindTvInput" msgid="5601264742478168987">"TV 입력 사용"</string>
@@ -742,6 +742,8 @@
<string name="permdesc_bindNotificationListenerService" msgid="985697918576902986">"권한을 가진 프로그램이 알림 수신기 서비스에 대한 최상위 인터페이스를 사용하도록 허용합니다. 일반 앱에는 필요하지 않습니다."</string>
<string name="permlab_bindConditionProviderService" msgid="1180107672332704641">"조건 제공자 서비스 사용"</string>
<string name="permdesc_bindConditionProviderService" msgid="1680513931165058425">"권한을 가진 프로그램이 조건 제공자 서비스의 최상위 인터페이스를 사용하도록 합니다. 일반 앱에는 필요하지 않습니다."</string>
+ <string name="permlab_bindMediaRouteService" msgid="6637740382272686835">"미디어 경로 서비스 사용"</string>
+ <string name="permdesc_bindMediaRouteService" msgid="6436655024972496687">"권한을 가진 프로그램이 미디어 경로 서비스의 최상위 인터페이스를 사용하도록 합니다. 일반 앱에는 필요하지 않습니다."</string>
<string name="permlab_bindDreamService" msgid="4153646965978563462">"드림 서비스에 연결"</string>
<string name="permdesc_bindDreamService" msgid="7325825272223347863">"권한을 가진 프로그램이 드림 서비스에 대한 최상위 인터페이스를 사용하도록 허용합니다. 일반 앱에는 필요하지 않습니다."</string>
<string name="permlab_invokeCarrierSetup" msgid="3699600833975117478">"이동통신사에서 제공한 구성 앱 호출"</string>
@@ -1283,6 +1285,11 @@
<skip />
<string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"Wi-Fi에 연결할 수 없습니다"</string>
<string name="wifi_watchdog_network_disabled_detailed" msgid="5548780776418332675">" 인터넷 연결 상태가 좋지 않습니다."</string>
+ <string name="wifi_connect_alert_title" msgid="8455846016001810172">"연결을 허용하시겠습니까?"</string>
+ <!-- String.format failed for translation -->
+ <!-- no translation found for wifi_connect_alert_message (8930084523889618078) -->
+ <skip />
+ <string name="wifi_connect_default_application" msgid="7143109390475484319">"앱"</string>
<string name="wifi_p2p_dialog_title" msgid="97611782659324517">"Wi-Fi Direct"</string>
<string name="wifi_p2p_turnon_message" msgid="2909250942299627244">"Wi-Fi Direct 작업을 시작합니다. 이 작업을 하면 Wi-Fi 클라이언트/핫스팟 작업이 중지됩니다."</string>
<string name="wifi_p2p_failed_message" msgid="3763669677935623084">"Wi-Fi Direct를 시작하지 못했습니다."</string>
@@ -1776,8 +1783,7 @@
<string name="lock_to_app_unlock_password" msgid="6380979775916974414">"고정 해제 이전에 비밀번호 요청"</string>
<string name="battery_saver_description" msgid="2510530476513605742">"배터리 수명을 개선하기 위해 배터리 절약에서는 기기의 성능을 줄이고 진동과 대부분의 백그라운드 데이터를 제한합니다. 동기화가 필요한 이메일, 채팅 메시지, 기타 앱은 열어야 업데이트됩니다.\n\n기기를 충전하는 중에는 배터리 절약이 자동으로 사용 중지됩니다."</string>
<string name="downtime_condition_summary" msgid="8761776337475705749">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g>에 정지가 종료될 때까지"</string>
- <!-- no translation found for downtime_condition_line_one (8762708714645352010) -->
- <skip />
+ <string name="downtime_condition_line_one" msgid="8762708714645352010">"다운타임이 끝날 때까지"</string>
<plurals name="zen_mode_duration_minutes_summary">
<item quantity="one" msgid="3177683545388923234">"1분(<xliff:g id="FORMATTEDTIME">%2$s</xliff:g>까지)"</item>
<item quantity="other" msgid="2787867221129368935">"%1$d분(<xliff:g id="FORMATTEDTIME">%2$s</xliff:g>까지)"</item>
@@ -1797,8 +1803,6 @@
<string name="zen_mode_until" msgid="7336308492289875088">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g>까지"</string>
<string name="zen_mode_forever" msgid="4316804956488785559">"무제한"</string>
<string name="toolbar_collapse_description" msgid="2821479483960330739">"접기"</string>
- <!-- no translation found for zen_mode_next_alarm_summary (5915140424683747372) -->
- <skip />
- <!-- no translation found for zen_mode_next_alarm_line_one (5537042951553420916) -->
- <skip />
+ <string name="zen_mode_next_alarm_summary" msgid="5915140424683747372">"다음 <xliff:g id="FORMATTEDTIME">%1$s</xliff:g> 알람까지"</string>
+ <string name="zen_mode_next_alarm_line_one" msgid="5537042951553420916">"다음 알람까지"</string>
</resources>
diff --git a/core/res/res/values-ky-rKG/strings.xml b/core/res/res/values-ky-rKG/strings.xml
index 67bb85c..2e5b512 100644
--- a/core/res/res/values-ky-rKG/strings.xml
+++ b/core/res/res/values-ky-rKG/strings.xml
@@ -47,9 +47,6 @@
<string name="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g> сек"</string>
<string name="durationSecond" msgid="985669622276420331">"<xliff:g id="SECONDS">%1$d</xliff:g> сек"</string>
<string name="untitled" msgid="4638956954852782576">"<Баш аты жок>"</string>
- <!-- no translation found for ellipsis (7899829516048813237) -->
- <skip />
- <string name="ellipsis_two_dots" msgid="1228078994866030736">"‥"</string>
<!-- no translation found for emptyPhoneNumber (7694063042079676517) -->
<skip />
<!-- no translation found for unknownName (2277556546742746522) -->
@@ -566,6 +563,8 @@
<!-- no translation found for permlab_bindRemoteViews (5697987759897367099) -->
<skip />
<string name="permdesc_bindRemoteViews" msgid="4717987810137692572">"Кармоочуга виджет кызматынын жогорку деңгээлдеги интерфейсине жалгашуу мүмкүнчүлүгүн берет. Кадимки колдонмолорго эч качан талап кылынбайт."</string>
+ <string name="permlab_bindRouteProvider" msgid="4869394607915096847">"багыт берүүчү кызматка жалгаштыруу"</string>
+ <string name="permdesc_bindRouteProvider" msgid="4703804520859960329">"Кармоочуга катталган багыт берүүчүлөргө жалгашуу мүмкүнчүлүгүн берет. Кадимки колдонмолорго эч качан талап кылынбайт."</string>
<!-- no translation found for permlab_bindDeviceAdmin (8704986163711455010) -->
<skip />
<string name="permdesc_bindDeviceAdmin" msgid="569715419543907930">"Кармоочуга түзмөк администраторуна ниетин билдирүү мүмкүнчүлүгүн берет. Кадимки колдонмолорго эч качан талап кылынбайт."</string>
@@ -955,6 +954,8 @@
<string name="permdesc_bindNotificationListenerService" msgid="985697918576902986">"Ээсине эскертүү тыңшагыч кызматтын жогорку деңгээл интерфейсине туташуу мүмкүнчүлүгүн берет. Жөнөкөй колдонмолордо эч качан керектелбейт."</string>
<string name="permlab_bindConditionProviderService" msgid="1180107672332704641">"шарт түзүүчү кызматына жалгаштыруу"</string>
<string name="permdesc_bindConditionProviderService" msgid="1680513931165058425">"Кармоочуга шарт түзүүчү кызматтын жогорку деңгээлдеги интерфейсине жалгашуу мүмкүнчүлүгүн берет. Кадимки колдонмолорго эч качан талап кылынбайт."</string>
+ <string name="permlab_bindMediaRouteService" msgid="6637740382272686835">"медиа жол кызматына жалгаштыруу"</string>
+ <string name="permdesc_bindMediaRouteService" msgid="6436655024972496687">"Кармоочуга медиа жол кызматынын жогорку деңгээл интерфейсин жалгаштырууга мүмкүндүк берет. Кадимки колдонмолорго эч качан талап кылынбайт."</string>
<string name="permlab_bindDreamService" msgid="4153646965978563462">"dream кызматына жалгаштыруу"</string>
<string name="permdesc_bindDreamService" msgid="7325825272223347863">"Кармоочуга dream кызматынын жогорку деңгээлдеги интерфейсине жалгашуу мүмкүнчүлүгүн берет. Кадимки колдонмолорго эч качан талап кылынбайт."</string>
<string name="permlab_invokeCarrierSetup" msgid="3699600833975117478">"оператордун конфигурациялык колдонмосун чакыруу"</string>
@@ -1654,6 +1655,9 @@
<skip />
<string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"Wi-Fi менен туташуу түзүлбөдү"</string>
<string name="wifi_watchdog_network_disabled_detailed" msgid="5548780776418332675">" хотспотунун интернет байланышы начар."</string>
+ <string name="wifi_connect_alert_title" msgid="8455846016001810172">"Туташууга уруксатпы?"</string>
+ <string name="wifi_connect_alert_message" msgid="8930084523889618078">"%1$s %2$s менен туташкысы келди"</string>
+ <string name="wifi_connect_default_application" msgid="7143109390475484319">"Колдонмо"</string>
<string name="wifi_p2p_dialog_title" msgid="97611782659324517">"Wi-Fi Direct"</string>
<string name="wifi_p2p_turnon_message" msgid="2909250942299627244">"Wi-Fi Дайректи иштетүү. Бул Wi-Fi клиентти/хотспотту өчүрөт."</string>
<string name="wifi_p2p_failed_message" msgid="3763669677935623084">"Wi-Fi Дайрект иштетилбеди."</string>
@@ -2256,8 +2260,7 @@
<string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Бошотуудан мурун сырсөз суралсын"</string>
<string name="battery_saver_description" msgid="2510530476513605742">"Батарея өмүрүн узартууга жардамдашуу үчүн, батарея үнөмдөгүч түзмөгүңүздүн өндүрүмдүүлүгүн азайтып, дирилдөөнү жана көпчүлүк фон дайындарын чектейт. Email, билдирүү жазуу жана башка шайкештирүүгө көз каранды колдонмолор, аларды ачмайыңызча жаңыртылбашы мүмкүн.\n\nТүзмөгүңүз кубатталып жатканда батарея үнөмдөгүч автоматтык түрдө өчөт."</string>
<string name="downtime_condition_summary" msgid="8761776337475705749">"Иштебей турган абал <xliff:g id="FORMATTEDTIME">%1$s</xliff:g> аяктамайынча"</string>
- <!-- no translation found for downtime_condition_line_one (8762708714645352010) -->
- <skip />
+ <string name="downtime_condition_line_one" msgid="8762708714645352010">"Аракетсиз убакытыңыз бүткүчө"</string>
<plurals name="zen_mode_duration_minutes_summary">
<item quantity="one" msgid="3177683545388923234">"Бир мүнөткө (<xliff:g id="FORMATTEDTIME">%2$s</xliff:g> чейин)"</item>
<item quantity="other" msgid="2787867221129368935">"%1$d мүнөткө (<xliff:g id="FORMATTEDTIME">%2$s</xliff:g> чейин)"</item>
@@ -2277,8 +2280,6 @@
<string name="zen_mode_until" msgid="7336308492289875088">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g> чейин"</string>
<string name="zen_mode_forever" msgid="4316804956488785559">"Белгисиз"</string>
<string name="toolbar_collapse_description" msgid="2821479483960330739">"Жыйнап коюу"</string>
- <!-- no translation found for zen_mode_next_alarm_summary (5915140424683747372) -->
- <skip />
- <!-- no translation found for zen_mode_next_alarm_line_one (5537042951553420916) -->
- <skip />
+ <string name="zen_mode_next_alarm_summary" msgid="5915140424683747372">"Саат <xliff:g id="FORMATTEDTIME">%1$s</xliff:g> боло турган кийинки айгайга чейин"</string>
+ <string name="zen_mode_next_alarm_line_one" msgid="5537042951553420916">"Кийинки айгайга чейин"</string>
</resources>
diff --git a/core/res/res/values-lo-rLA/strings.xml b/core/res/res/values-lo-rLA/strings.xml
index 4549586..e809bdf 100644
--- a/core/res/res/values-lo-rLA/strings.xml
+++ b/core/res/res/values-lo-rLA/strings.xml
@@ -41,8 +41,6 @@
<string name="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g> ວິ"</string>
<string name="durationSecond" msgid="985669622276420331">"<xliff:g id="SECONDS">%1$d</xliff:g> ວິ"</string>
<string name="untitled" msgid="4638956954852782576">"<ບໍ່ມີຊື່>"</string>
- <string name="ellipsis" msgid="7899829516048813237">"…"</string>
- <string name="ellipsis_two_dots" msgid="1228078994866030736">"‥"</string>
<string name="emptyPhoneNumber" msgid="7694063042079676517">"(ບໍ່ມີເບີໂທລະສັບ)"</string>
<string name="unknownName" msgid="2277556546742746522">"(ບໍ່ຮູ້)"</string>
<string name="defaultVoiceMailAlphaTag" msgid="2660020990097733077">"ຂໍ້ຄວາມສຽງ"</string>
@@ -415,6 +413,8 @@
<string name="permdesc_bindRemoteDisplay" msgid="1261242718727295981">"ອະນຸຍາດໃຫ້ຜູ່ຖືຜູກກັບສ່ວນຕິດຕໍ່ລະດັບສູງສຸດ ຂອງການສະແດງຜົນທາງໄກ. ບໍ່ຈຳເປັນສຳລັບແອັບຯທົ່ວໄປ."</string>
<string name="permlab_bindRemoteViews" msgid="5697987759897367099">"ເຊື່ອມໂຍງໄປຫາບໍລິການວິດເຈັດ"</string>
<string name="permdesc_bindRemoteViews" msgid="4717987810137692572">"ອະນຸຍາດໃຫ້ຜູ່ຖືຜູກກັບອິນເຕີເຟດລະດັບສູງສຸດ ຂອງບໍລິການວິເຈັດ. ບໍ່ຈຳເປັນສຳລັບແອັບຯທົ່ວໄປ."</string>
+ <string name="permlab_bindRouteProvider" msgid="4869394607915096847">"ເຊື່ອມໂຍງກັບການບໍລິການຂອງຜູ່ໃຫ້ບໍລິການເສັ້ນທາງ"</string>
+ <string name="permdesc_bindRouteProvider" msgid="4703804520859960329">"ອະນຸຍາດໃຫ້ເຈົ້າຂອງສາມາດເຊື່ອມໂຍງກັບທຸກໆຜູ່ໃຫ້ບໍລິການເສັ້ນທາງທີ່ລົງທະບຽນ. ບໍ່ຄວນຈະໄດ້ໃຊ້ໃນແອັບຯທົ່ວໄປ."</string>
<string name="permlab_bindDeviceAdmin" msgid="8704986163711455010">"ຕິດຕໍ່ກັບຜູ່ເບິ່ງແຍງອຸປະກອນ"</string>
<string name="permdesc_bindDeviceAdmin" msgid="569715419543907930">"ອະນຸຍາດໃຫ້ເຈົ້າຂອງສົ່ງເຈດຕະນາຫາຜູ່ເບິ່ງແຍງລະບົບອຸປະກອນ. ແອັບຯທົ່ວໄປບໍ່ຄວນຈຳເປັນຕ້ອງໃຊ້."</string>
<string name="permlab_bindTvInput" msgid="5601264742478168987">"ຜູກກັບການປ້ອນຂໍ້ມູນເຂົ້າໂທລະທັດ"</string>
@@ -742,6 +742,8 @@
<string name="permdesc_bindNotificationListenerService" msgid="985697918576902986">"ອະນຸຍາດໃຫ້ເຈົ້າຂອງເຊື່ອມໂຍງສ່ວນຕິດຕໍ່ລະດັບເທິງສຸດ ຂອງຜູ່ຟັງບໍລິການການແຈ້ງເຕືອນ. ບໍ່ຈຳເປັນສຳລັບແອັບຯທົ່ວໄປ."</string>
<string name="permlab_bindConditionProviderService" msgid="1180107672332704641">"ເຊື່ອມໂຍງກັບບໍລິການຜູ່ສະໜອງເງື່ອນໄຂ"</string>
<string name="permdesc_bindConditionProviderService" msgid="1680513931165058425">"ອະນຸຍາດໃຫ້ເຈົ້າຂອງເຊື່ອມໂຍງສ່ວນຕິດຕໍ່ລະດັບສູງສຸດຂອງບໍລິການສະໜອງເງື່ອນໄຂ. ບໍ່ຈຳເປັນສຳລັບແອັບຯທົ່ວໄປ."</string>
+ <string name="permlab_bindMediaRouteService" msgid="6637740382272686835">"ເຊື່ອມໂຍງກັບບໍລິການເສັ້ນທາງມີເດຍ"</string>
+ <string name="permdesc_bindMediaRouteService" msgid="6436655024972496687">"ອະນຸຍາດໃຫ້ຜູ່ໃຊ້ເຊື່ອມໂຍງກັບສ່ວນຕິດຕໍ່ຜູ່ໃຊ້ລະດັບສູງສຸດຂອງບໍລິການເສັ້ນທາງມີເດຍ. ແອັບຯທົ່ວໄປບໍ່ຄວນຕ້ອງໃຊ້."</string>
<string name="permlab_bindDreamService" msgid="4153646965978563462">"ຜູກກັບບໍລິການ dream"</string>
<string name="permdesc_bindDreamService" msgid="7325825272223347863">"ອະນຸຍາດໃຫ້ຜູ່ຖືຜູກກັບສ່ວນຕິດຕໍ່ລະດັບສູງສຸດ ຂອງບໍລິການ dream. ບໍ່ຈຳເປັນສຳລັບແອັບຯທົ່ວໄປ."</string>
<string name="permlab_invokeCarrierSetup" msgid="3699600833975117478">"ຮ້ອງຂໍແອັບຯປັບຄ່າທີ່ສະໜອງໂດຍຜູ່ໃຫ້ບໍລິການ"</string>
@@ -1283,6 +1285,9 @@
<skip />
<string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"ບໍ່ສາມາດເຊື່ອມຕໍ່ Wi-Fi ໄດ້"</string>
<string name="wifi_watchdog_network_disabled_detailed" msgid="5548780776418332675">" ມີສັນຍານອິນເຕີເນັດທີ່ບໍ່ດີ."</string>
+ <string name="wifi_connect_alert_title" msgid="8455846016001810172">"ອະນຸຍາດການເຊື່ອມຕໍ່ຫຼືບໍ່?"</string>
+ <string name="wifi_connect_alert_message" msgid="8930084523889618078">"%1$s ຕ້ອງການທີ່ຈະເຊື່ອມຕໍ່ຫາ %2$s"</string>
+ <string name="wifi_connect_default_application" msgid="7143109390475484319">"ແອັບພລິເຄຊັນ"</string>
<string name="wifi_p2p_dialog_title" msgid="97611782659324517">"Wi-Fi Direct"</string>
<string name="wifi_p2p_turnon_message" msgid="2909250942299627244">"ເລີ່ມ Wi-Fi Direct. ນີ້ຈະເປັນການປິດ Wi-Fi client/hotspot."</string>
<string name="wifi_p2p_failed_message" msgid="3763669677935623084">"ບໍ່ສາມາດເລີ່ມ Wi-Fi Direct ໄດ້."</string>
diff --git a/core/res/res/values-lt/strings.xml b/core/res/res/values-lt/strings.xml
index d8758eb..f756181 100644
--- a/core/res/res/values-lt/strings.xml
+++ b/core/res/res/values-lt/strings.xml
@@ -41,8 +41,6 @@
<string name="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g> sek."</string>
<string name="durationSecond" msgid="985669622276420331">"<xliff:g id="SECONDS">%1$d</xliff:g> sek."</string>
<string name="untitled" msgid="4638956954852782576">"<Be pavadinimo>"</string>
- <string name="ellipsis" msgid="7899829516048813237">"…"</string>
- <string name="ellipsis_two_dots" msgid="1228078994866030736">"‥"</string>
<string name="emptyPhoneNumber" msgid="7694063042079676517">"(Nėra telefono numerio)"</string>
<string name="unknownName" msgid="2277556546742746522">"(Nežinomas)"</string>
<string name="defaultVoiceMailAlphaTag" msgid="2660020990097733077">"Balso paštas"</string>
@@ -415,6 +413,8 @@
<string name="permdesc_bindRemoteDisplay" msgid="1261242718727295981">"Leidžiama savininkui susisaistyti su aukščiausiojo lygio nuotolinio ekrano sąsaja. Įprastoms programoms to neturėtų prireikti."</string>
<string name="permlab_bindRemoteViews" msgid="5697987759897367099">"susaistyti su valdiklio paslauga"</string>
<string name="permdesc_bindRemoteViews" msgid="4717987810137692572">"Leidžiama savininkui susisaistyti su aukščiausio lygio valdiklio paslaugos sąsaja. Įprastoms programoms to neturėtų prireikti."</string>
+ <string name="permlab_bindRouteProvider" msgid="4869394607915096847">"susisaistyti su maršruto parinkimo paslauga"</string>
+ <string name="permdesc_bindRouteProvider" msgid="4703804520859960329">"Savininkui leidžiama susisaistyti su bet kokiomis registruotomis maršrutų parinkimo paslaugomis. To niekada neturėtų prireikti naudojant įprastas programas."</string>
<string name="permlab_bindDeviceAdmin" msgid="8704986163711455010">"sąveikauti su įrenginio administratoriumi"</string>
<string name="permdesc_bindDeviceAdmin" msgid="569715419543907930">"Leidžiama savininkui siųsti tikslus įrenginio administratoriui. Įprastoms programoms to neturėtų prireikti."</string>
<string name="permlab_bindTvInput" msgid="5601264742478168987">"susisaistyti su TV įvestimi"</string>
@@ -742,6 +742,8 @@
<string name="permdesc_bindNotificationListenerService" msgid="985697918576902986">"Leidžiama turėtojui susisaistyti su pranešimų skaitymo priemonės paslaugos aukščiausio lygio sąsaja. Įprastoms programoms to neturėtų prireikti."</string>
<string name="permlab_bindConditionProviderService" msgid="1180107672332704641">"susaistyti su sąlygos teikėjo paslauga"</string>
<string name="permdesc_bindConditionProviderService" msgid="1680513931165058425">"Turėtojui leidžiama susaistyti programą su sąlygos teikėjo paslaugos aukščiausio lygio sąsaja. Įprastoms programoms to niekada neturėtų prireikti."</string>
+ <string name="permlab_bindMediaRouteService" msgid="6637740382272686835">"susaistyti su medijos maršruto paslauga"</string>
+ <string name="permdesc_bindMediaRouteService" msgid="6436655024972496687">"Leidžiama savininką susaistyti su aukščiausio lygio medijos maršruto paslaugos sąsaja. Niekada neturėtų būti reikalinga įprastoms programoms."</string>
<string name="permlab_bindDreamService" msgid="4153646965978563462">"susisaistyti su mėgstama paslauga"</string>
<string name="permdesc_bindDreamService" msgid="7325825272223347863">"Savininkui leidžiama susisaistyti su mėgstamos paslaugos aukščiausio lygio sąsaja. Įprastoms programoms to neturėtų prireikti."</string>
<string name="permlab_invokeCarrierSetup" msgid="3699600833975117478">"iškviesti operatoriaus pateiktą konfigūravimo programą"</string>
@@ -1283,6 +1285,9 @@
<skip />
<string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"Nepavyko prisijungti prie „Wi-Fi“"</string>
<string name="wifi_watchdog_network_disabled_detailed" msgid="5548780776418332675">" turi prastą interneto ryšį."</string>
+ <string name="wifi_connect_alert_title" msgid="8455846016001810172">"Leisti prisijungti?"</string>
+ <string name="wifi_connect_alert_message" msgid="8930084523889618078">"„%1$s“ nori prisijungti prie „%2$s“"</string>
+ <string name="wifi_connect_default_application" msgid="7143109390475484319">"Programa"</string>
<string name="wifi_p2p_dialog_title" msgid="97611782659324517">"Tiesioginis „Wi-Fi“ ryšys"</string>
<string name="wifi_p2p_turnon_message" msgid="2909250942299627244">"Paleiskite „Wi-Fi Direct“. Bus išjungta „Wi-Fi“ programa / viešosios interneto prieigos taškas."</string>
<string name="wifi_p2p_failed_message" msgid="3763669677935623084">"Nepavyko paleisti „Wi-Fi Direct“."</string>
@@ -1776,8 +1781,7 @@
<string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Prašyti slaptažodžio prieš atsegant"</string>
<string name="battery_saver_description" msgid="2510530476513605742">"Siekiant pailginti akumuliatoriaus veikimo laiką, Akumuliatoriaus tausojimo priemonė sumažina įrenginio našumą ir apriboja vibravimą bei daugumą foninių duomenų. El. paštas, pranešimų siuntimas ir kitos programos, kurios veikia sinchronizavimo pagrindu, gali nebūti atnaujintos, nebent jas atidarysite.\n\nKraunant įrenginį Akumuliatoriaus tausojimo priemonė automatiškai išjungiama."</string>
<string name="downtime_condition_summary" msgid="8761776337475705749">"Kol jūsų prastova baigsis <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
- <!-- no translation found for downtime_condition_line_one (8762708714645352010) -->
- <skip />
+ <string name="downtime_condition_line_one" msgid="8762708714645352010">"Kol baigsis prastova"</string>
<plurals name="zen_mode_duration_minutes_summary">
<item quantity="one" msgid="3177683545388923234">"Vieną minutę (iki <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
<item quantity="other" msgid="2787867221129368935">"%1$d min. (iki <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
@@ -1797,8 +1801,6 @@
<string name="zen_mode_until" msgid="7336308492289875088">"Iki <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
<string name="zen_mode_forever" msgid="4316804956488785559">"Neapibrėžta"</string>
<string name="toolbar_collapse_description" msgid="2821479483960330739">"Sutraukti"</string>
- <!-- no translation found for zen_mode_next_alarm_summary (5915140424683747372) -->
- <skip />
- <!-- no translation found for zen_mode_next_alarm_line_one (5537042951553420916) -->
- <skip />
+ <string name="zen_mode_next_alarm_summary" msgid="5915140424683747372">"Iki kito įspėjimo <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
+ <string name="zen_mode_next_alarm_line_one" msgid="5537042951553420916">"Iki kito įspėjimo"</string>
</resources>
diff --git a/core/res/res/values-lv/strings.xml b/core/res/res/values-lv/strings.xml
index 156dc94..fccbf43 100644
--- a/core/res/res/values-lv/strings.xml
+++ b/core/res/res/values-lv/strings.xml
@@ -41,8 +41,6 @@
<string name="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g> s"</string>
<string name="durationSecond" msgid="985669622276420331">"<xliff:g id="SECONDS">%1$d</xliff:g> s"</string>
<string name="untitled" msgid="4638956954852782576">"<Bez nosaukuma>"</string>
- <string name="ellipsis" msgid="7899829516048813237">"…"</string>
- <string name="ellipsis_two_dots" msgid="1228078994866030736">"‥"</string>
<string name="emptyPhoneNumber" msgid="7694063042079676517">"(Nav tālruņa numura)"</string>
<string name="unknownName" msgid="2277556546742746522">"(Nezināms)"</string>
<string name="defaultVoiceMailAlphaTag" msgid="2660020990097733077">"Balss pasts"</string>
@@ -415,6 +413,8 @@
<string name="permdesc_bindRemoteDisplay" msgid="1261242718727295981">"Ļauj īpašniekam izveidot saiti ar attāla displeja augšējā līmeņa saskarni. Parastajām lietotnēm tas nekad nav nepieciešams."</string>
<string name="permlab_bindRemoteViews" msgid="5697987759897367099">"saistīt ar logrīka pakalpojumu"</string>
<string name="permdesc_bindRemoteViews" msgid="4717987810137692572">"Ļauj īpašniekam izveidot saiti ar logrīka pakalpojuma augšējā līmeņa saskarni. Parastajām lietotnēm tas nekad nav nepieciešams."</string>
+ <string name="permlab_bindRouteProvider" msgid="4869394607915096847">"Saistīšana ar maršruta nodrošinātāja pakalpojumu"</string>
+ <string name="permdesc_bindRouteProvider" msgid="4703804520859960329">"Ļauj īpašniekam saistīt jebkādus reģistrētus maršrutēšanas nodrošinātājus. Parastām lietotnēm šī atļauja nekad nav nepieciešama."</string>
<string name="permlab_bindDeviceAdmin" msgid="8704986163711455010">"mijiedarboties ar ierīces administratoru"</string>
<string name="permdesc_bindDeviceAdmin" msgid="569715419543907930">"Ļauj īpašniekam nosūtīt informāciju par nodomiem ierīces administratoram. Parastajām lietotnēm tas nekad nav nepieciešams."</string>
<string name="permlab_bindTvInput" msgid="5601264742478168987">"Izveidot saiti ar TV ieeju"</string>
@@ -742,6 +742,8 @@
<string name="permdesc_bindNotificationListenerService" msgid="985697918576902986">"Ļauj īpašniekam izveidot saiti ar paziņojumu uztvērēja pakalpojuma augšējā līmeņa saskarni. Parastajām lietotnēm tas nekad nav nepieciešams."</string>
<string name="permlab_bindConditionProviderService" msgid="1180107672332704641">"Saistīšana ar nosacījumu sniedzēja pakalpojumu"</string>
<string name="permdesc_bindConditionProviderService" msgid="1680513931165058425">"Ļauj īpašniekam izveidot savienojumu ar drukas nosacījumu sniedzēja pakalpojuma augšējā līmeņa saskarni. Parastajām lietotnēm tas nekad nav nepieciešams."</string>
+ <string name="permlab_bindMediaRouteService" msgid="6637740382272686835">"Saistīšana ar multivides datu maršrutēšanas pakalpojumu"</string>
+ <string name="permdesc_bindMediaRouteService" msgid="6436655024972496687">"Ļauj īpašniekam izveidot saiti ar multivides datu maršrutēšanas pakalpojuma augstākā līmeņa saskarni. Nekad nav nepieciešama parastām lietotnēm."</string>
<string name="permlab_bindDreamService" msgid="4153646965978563462">"piesaistīt ekrānsaudzētāja pakalpojumu"</string>
<string name="permdesc_bindDreamService" msgid="7325825272223347863">"Ļauj īpašniekam piesaistīt ekrānsaudzētāja pakalpojuma augšējā līmeņa saskarni. Parastajām lietotnēm tas nekad nav nepieciešams."</string>
<string name="permlab_invokeCarrierSetup" msgid="3699600833975117478">"Operatora nodrošinātas konfigurācijas lietotnes izsaukšana"</string>
@@ -1283,6 +1285,9 @@
<skip />
<string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"Nevarēja izveidot savienojumu ar Wi-Fi."</string>
<string name="wifi_watchdog_network_disabled_detailed" msgid="5548780776418332675">" ir slikts interneta savienojums."</string>
+ <string name="wifi_connect_alert_title" msgid="8455846016001810172">"Vai atļaut savienojumu?"</string>
+ <string name="wifi_connect_alert_message" msgid="8930084523889618078">"%1$s vēlas izveidot savienojumu ar tīklu %2$s"</string>
+ <string name="wifi_connect_default_application" msgid="7143109390475484319">"Lietojumprogramma"</string>
<string name="wifi_p2p_dialog_title" msgid="97611782659324517">"Wi-Fi Direct"</string>
<string name="wifi_p2p_turnon_message" msgid="2909250942299627244">"Palaist programmu Wi-Fi Direct. Tādējādi tiks izslēgta Wi-Fi klienta/tīklāja darbība."</string>
<string name="wifi_p2p_failed_message" msgid="3763669677935623084">"Nevarēja palaist programmu Wi-Fi Direct."</string>
diff --git a/core/res/res/values-mk-rMK/strings.xml b/core/res/res/values-mk-rMK/strings.xml
index fc50a51..8979d4a 100644
--- a/core/res/res/values-mk-rMK/strings.xml
+++ b/core/res/res/values-mk-rMK/strings.xml
@@ -41,8 +41,6 @@
<string name="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g> сек."</string>
<string name="durationSecond" msgid="985669622276420331">"<xliff:g id="SECONDS">%1$d</xliff:g> сек."</string>
<string name="untitled" msgid="4638956954852782576">"<Без наслов>"</string>
- <string name="ellipsis" msgid="7899829516048813237">"…"</string>
- <string name="ellipsis_two_dots" msgid="1228078994866030736">"‥"</string>
<string name="emptyPhoneNumber" msgid="7694063042079676517">"(Нема телефонски број)"</string>
<string name="unknownName" msgid="2277556546742746522">"(Непознато)"</string>
<string name="defaultVoiceMailAlphaTag" msgid="2660020990097733077">"Говорна пошта"</string>
@@ -415,6 +413,8 @@
<string name="permdesc_bindRemoteDisplay" msgid="1261242718727295981">"Овозможува сопственикот да се поврзе со интерфејс од највисоко ниво на приказ од далечина. Не треба да се користи за стандардни апликации."</string>
<string name="permlab_bindRemoteViews" msgid="5697987759897367099">"врзи се со услуга за виџет"</string>
<string name="permdesc_bindRemoteViews" msgid="4717987810137692572">"Дозволува сопственикот да се поврзе со интерфејс од највисоко ниво на услугата за додатоци. Не треба да се користи за стандардни апликации."</string>
+ <string name="permlab_bindRouteProvider" msgid="4869394607915096847">"поврзување со услуга за давател на маршрута"</string>
+ <string name="permdesc_bindRouteProvider" msgid="4703804520859960329">"Дозволува сопственикот да се поврзе со сите регистрирани даватели на маршрути. Не треба да се користи за стандардни апликации."</string>
<string name="permlab_bindDeviceAdmin" msgid="8704986163711455010">"комуницирај со администратор на уред"</string>
<string name="permdesc_bindDeviceAdmin" msgid="569715419543907930">"Дозволува сопственикот да испраќа намери до администратор за уреди. Не треба да се користи за стандардни апликации."</string>
<string name="permlab_bindTvInput" msgid="5601264742478168987">"поврзување со ТВ-влез"</string>
@@ -742,6 +742,8 @@
<string name="permdesc_bindNotificationListenerService" msgid="985697918576902986">"Овозможува сопственикот да се поврзе со интерфејс од највисоко ниво на услугата слушател на известувања. Не треба да се користи за стандардни апликации."</string>
<string name="permlab_bindConditionProviderService" msgid="1180107672332704641">"поврзување со услуга за давател на услов"</string>
<string name="permdesc_bindConditionProviderService" msgid="1680513931165058425">"Дозволува сопственикот да се поврзе со интерфејс од највисоко ниво на давател на услуги за услов. Не треба да се користи за стандардни апликации."</string>
+ <string name="permlab_bindMediaRouteService" msgid="6637740382272686835">"врзува со услуга за насочување медиуми"</string>
+ <string name="permdesc_bindMediaRouteService" msgid="6436655024972496687">"Овозможува носителот да се врзува со интерфејс на највисоко ниво на услуга за насочување медиуми. Не би требало да е потребно за стандардни апликации."</string>
<string name="permlab_bindDreamService" msgid="4153646965978563462">"поврзи се со услугата мечтаење"</string>
<string name="permdesc_bindDreamService" msgid="7325825272223347863">"Дозволува сопственикот да се поврзе со интерфејс од највисоко ниво на услугата мечтаење. Не треба да се користи за стандардни апликации."</string>
<string name="permlab_invokeCarrierSetup" msgid="3699600833975117478">"повикај конфигурација на апликацијата обезбедена од давателот"</string>
@@ -1283,6 +1285,9 @@
<skip />
<string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"Не можеше да се поврзе со Wi-Fi"</string>
<string name="wifi_watchdog_network_disabled_detailed" msgid="5548780776418332675">" има слаба конекција на интернет."</string>
+ <string name="wifi_connect_alert_title" msgid="8455846016001810172">"Дозволете поврзување?"</string>
+ <string name="wifi_connect_alert_message" msgid="8930084523889618078">"%1$s сака да се поврзе на %2$s"</string>
+ <string name="wifi_connect_default_application" msgid="7143109390475484319">"Апликација"</string>
<string name="wifi_p2p_dialog_title" msgid="97611782659324517">"Wi-Fi Direct"</string>
<string name="wifi_p2p_turnon_message" msgid="2909250942299627244">"Започни Wi-Fi Direct. Ова ќе го исклучи Wi-Fi клиентот/хточката на пристап."</string>
<string name="wifi_p2p_failed_message" msgid="3763669677935623084">"Не можеше да се стартува Wi-Fi Direct."</string>
@@ -1778,8 +1783,7 @@
<string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Прашај за лозинка пред откачување"</string>
<string name="battery_saver_description" msgid="2510530476513605742">"За да помогне во подобрување на трајноста на батеријата, штедачот на батерија го намалува учинокот на уредот и ги ограничува вибрациите и повеќето податоци во заднина. Е-поштата, испраќањето пораки и другите апликации кои се потпираат на синхронизирање може да не се ажурираат освен ако не ги отворите.\n\nШтедачот на батерија автоматски се исклучува кога уредот се полни."</string>
<string name="downtime_condition_summary" msgid="8761776337475705749">"Додека не заврши паузата во <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
- <!-- no translation found for downtime_condition_line_one (8762708714645352010) -->
- <skip />
+ <string name="downtime_condition_line_one" msgid="8762708714645352010">"Додека да заврши паузата"</string>
<plurals name="zen_mode_duration_minutes_summary">
<item quantity="one" msgid="3177683545388923234">"Една минута (до <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
<item quantity="other" msgid="2787867221129368935">"%1$d минути (до <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
@@ -1799,8 +1803,6 @@
<string name="zen_mode_until" msgid="7336308492289875088">"До <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
<string name="zen_mode_forever" msgid="4316804956488785559">"Неодредено време"</string>
<string name="toolbar_collapse_description" msgid="2821479483960330739">"Собери"</string>
- <!-- no translation found for zen_mode_next_alarm_summary (5915140424683747372) -->
- <skip />
- <!-- no translation found for zen_mode_next_alarm_line_one (5537042951553420916) -->
- <skip />
+ <string name="zen_mode_next_alarm_summary" msgid="5915140424683747372">"До следниот аларм во <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
+ <string name="zen_mode_next_alarm_line_one" msgid="5537042951553420916">"До следниот аларм"</string>
</resources>
diff --git a/core/res/res/values-ml-rIN/strings.xml b/core/res/res/values-ml-rIN/strings.xml
index 1c271d1..eecdf93 100644
--- a/core/res/res/values-ml-rIN/strings.xml
+++ b/core/res/res/values-ml-rIN/strings.xml
@@ -41,8 +41,6 @@
<string name="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g> സെക്കൻഡ്"</string>
<string name="durationSecond" msgid="985669622276420331">"<xliff:g id="SECONDS">%1$d</xliff:g> സെക്കൻഡ്"</string>
<string name="untitled" msgid="4638956954852782576">"<ശീർഷകമില്ലാത്ത>"</string>
- <string name="ellipsis" msgid="7899829516048813237">"…"</string>
- <string name="ellipsis_two_dots" msgid="1228078994866030736">"‥"</string>
<string name="emptyPhoneNumber" msgid="7694063042079676517">"(ഫോൺ നമ്പറില്ല)"</string>
<string name="unknownName" msgid="2277556546742746522">"(അജ്ഞാതം)"</string>
<string name="defaultVoiceMailAlphaTag" msgid="2660020990097733077">"വോയ്സ് മെയില്"</string>
@@ -415,6 +413,8 @@
<string name="permdesc_bindRemoteDisplay" msgid="1261242718727295981">"ഒരു വിദൂര ഡിസ്പ്ലേയുടെ ഉയർന്ന നിലയിലുള്ള ഇന്റർഫേസിലേക്ക് ബന്ധിപ്പിക്കാൻ ഹോൾഡറിനെ അനുവദിക്കുന്നു. സാധാരണ അപ്ലിക്കേഷനുകൾക്ക് ഒരിക്കലും ആവശ്യമില്ല."</string>
<string name="permlab_bindRemoteViews" msgid="5697987759897367099">"ഒരു വിജറ്റ് സേവനവുമായി ബന്ധിപ്പിക്കുക"</string>
<string name="permdesc_bindRemoteViews" msgid="4717987810137692572">"ഒരു വിജറ്റ് സേവനത്തിന്റെ ഉയർന്ന നിലയിലുള്ള ഇന്റർഫേസിലേക്ക് ബന്ധിപ്പിക്കാൻ ഹോൾഡറിനെ അനുവദിക്കുന്നു. സാധാരണ അപ്ലിക്കേഷനുകൾക്ക് ഒരിക്കലും ആവശ്യമില്ല."</string>
+ <string name="permlab_bindRouteProvider" msgid="4869394607915096847">"റൂട്ട് പ്രൊവൈഡർ സേവനവുമായി ബന്ധിപ്പിക്കുക"</string>
+ <string name="permdesc_bindRouteProvider" msgid="4703804520859960329">"ഏതെങ്കിലും രജിസ്റ്റർചെയ്ത റൂട്ട് ദാതാക്കളുമായി ബന്ധിപ്പിക്കാൻ ഹോൾഡറിനെ അനുവദിക്കുന്നു. സാധാരണ അപ്ലിക്കേഷനുകൾക്ക് ഒരിക്കലും ആവശ്യമില്ല."</string>
<string name="permlab_bindDeviceAdmin" msgid="8704986163711455010">"ഒരു ഉപകരണ അഡ്മിനുമായി സംവദിക്കുക"</string>
<string name="permdesc_bindDeviceAdmin" msgid="569715419543907930">"ഒരു ഉപകരണ അഡ്മിനിസ്ട്രേറ്ററിലേക്ക് ഇന്റന്റുകൾ അയയ്ക്കുന്നതിന് ദാതാവിനെ അനുവദിക്കുന്നു. സാധാരണ അപ്ലിക്കേഷനുകൾക്ക് ഒരിക്കലും ആവശ്യമില്ല."</string>
<string name="permlab_bindTvInput" msgid="5601264742478168987">"TV ഇൻപുട്ടുമായി ബന്ധിപ്പിക്കുക"</string>
@@ -742,6 +742,8 @@
<string name="permdesc_bindNotificationListenerService" msgid="985697918576902986">"ഒരു അറിയിപ്പ് ലിസണർ സേവനത്തിന്റെ ഉയർന്ന നിലയിലുള്ള ഇന്റർഫേസിലേക്ക് ബന്ധിപ്പിക്കാൻ ഹോൾഡറിനെ അനുവദിക്കുന്നു. സാധാരണ അപ്ലിക്കേഷനുകൾക്ക് ഒരിക്കലും ആവശ്യമില്ല."</string>
<string name="permlab_bindConditionProviderService" msgid="1180107672332704641">"കണ്ടീഷൻ പ്രൊവൈഡർ സേവനവുമായി ബന്ധിപ്പിക്കുക"</string>
<string name="permdesc_bindConditionProviderService" msgid="1680513931165058425">"ഒരു കണ്ടീഷൻ പ്രൊവൈഡർ സേവനത്തിന്റെ ഉയർന്ന നിലയിലുള്ള ഇന്റർഫേസിലേക്ക് ബന്ധിപ്പിക്കാൻ ഹോൾഡറിനെ അനുവദിക്കുന്നു. സാധാരണ അപ്ലിക്കേഷനുകൾക്ക് ഒരിക്കലും ആവശ്യമില്ല."</string>
+ <string name="permlab_bindMediaRouteService" msgid="6637740382272686835">"മീഡിയ റൂട്ട് സേവനവുമായി ബന്ധിപ്പിക്കുക"</string>
+ <string name="permdesc_bindMediaRouteService" msgid="6436655024972496687">"ഒരു മീഡിയ റൂട്ട് സേവനത്തിന്റെ ഉയർന്ന നിലയിലുള്ള ഇന്റർഫേസിലേക്ക് ബന്ധിപ്പിക്കാൻ ദാതാവിനെ അനുവദിക്കുന്നു. സാധാരണ അപ്ലിക്കേഷനുകൾക്ക് ഒരിക്കലും ആവശ്യമില്ല."</string>
<string name="permlab_bindDreamService" msgid="4153646965978563462">"സ്വപ്നതുല്യമായ ഒരു സേവനത്തിലേക്ക് ബന്ധിപ്പിക്കുക"</string>
<string name="permdesc_bindDreamService" msgid="7325825272223347863">"സ്വപ്നതുല്യമായ ഒരു സേവനത്തിന്റെ ഉയർന്ന നിലയിലുള്ള ഇന്റർഫേസിലേക്ക് ബന്ധിപ്പിക്കാൻ ദാതാവിനെ അനുവദിക്കുന്നു. സാധാരണ അപ്ലിക്കേഷനുകൾക്ക് ഒരിക്കലും ആവശ്യമില്ല."</string>
<string name="permlab_invokeCarrierSetup" msgid="3699600833975117478">"കാരിയർ നൽകിയ കോൺഫിഗറേഷൻ അപ്ലിക്കേഷൻ റദ്ദാക്കുക"</string>
@@ -1283,6 +1285,9 @@
<skip />
<string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"Wi-Fi-ലേക്ക് കണക്റ്റുചെയ്യാൻ കഴിഞ്ഞില്ല"</string>
<string name="wifi_watchdog_network_disabled_detailed" msgid="5548780776418332675">" മോശം ഇന്റർനെറ്റ് കണക്ഷനാണുള്ളത്."</string>
+ <string name="wifi_connect_alert_title" msgid="8455846016001810172">"കണക്ഷൻ അനുവദിക്കണോ?"</string>
+ <string name="wifi_connect_alert_message" msgid="8930084523889618078">"%1$s, %2$s എന്നതിലേക്ക് കണക്റ്റുചെയ്യാൻ ആഗ്രഹിക്കുന്നു"</string>
+ <string name="wifi_connect_default_application" msgid="7143109390475484319">"ഒരു അപ്ലിക്കേഷൻ"</string>
<string name="wifi_p2p_dialog_title" msgid="97611782659324517">"Wi-Fi ഡയറക്ട്"</string>
<string name="wifi_p2p_turnon_message" msgid="2909250942299627244">"Wi-Fi ഡയറക്റ്റ് ആരംഭിക്കുക. ഇത് Wi-Fi ക്ലയന്റ്/ഹോട്ട്സ്പോട്ട് ഓഫാക്കും."</string>
<string name="wifi_p2p_failed_message" msgid="3763669677935623084">"Wi-Fi ഡയറക്റ്റ് ആരംഭിക്കാനായില്ല."</string>
@@ -1776,8 +1781,7 @@
<string name="lock_to_app_unlock_password" msgid="6380979775916974414">"അൺപിൻ ചെയ്യുന്നതിനുമുമ്പ് പാസ്വേഡ് ആവശ്യപ്പെടുക"</string>
<string name="battery_saver_description" msgid="2510530476513605742">"ബാറ്ററി ആയുസ്സ് മെച്ചപ്പെടുത്താൻ സഹായിക്കുന്നതിന്, ബാറ്ററി സേവർ നിങ്ങളുടെ ഉപകരണത്തിന്റെ പ്രകടനത്തെ കുറയ്ക്കുകയും വൈബ്രേഷനെയും മിക്ക പശ്ചാത്തല ഡാറ്റയെയും പരിമിതപ്പെടുത്തുകയും ചെയ്യുന്നു. ഇമെയിൽ, സന്ദേശമയയ്ക്കൽ, സമന്വയിപ്പിക്കലിനെ ആശ്രയിച്ചുള്ള മറ്റ് അപ്ലിക്കേഷനുകൾ എന്നിവ നിങ്ങൾ തുറക്കുന്നതുവരെ അപ്ഡേറ്റുചെയ്യാനിടയില്ല.\n\nനിങ്ങളുടെ ഉപകരണം ചാർജ്ജുചെയ്യുമ്പോൾ ബാറ്ററി സേവർ യാന്ത്രികമായി ഓഫാകും."</string>
<string name="downtime_condition_summary" msgid="8761776337475705749">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g>-ന് നിങ്ങളുടെ കാലാവധി അവസാനിക്കുന്നതുവരെ"</string>
- <!-- no translation found for downtime_condition_line_one (8762708714645352010) -->
- <skip />
+ <string name="downtime_condition_line_one" msgid="8762708714645352010">"പ്രവർത്തനരഹിതമായിരിക്കുന്ന സമയം അവസാനിക്കുന്നതുവരെ"</string>
<!-- String.format failed for translation -->
<!-- no translation found for zen_mode_duration_minutes_summary:other (2787867221129368935) -->
<plurals name="zen_mode_duration_hours_summary">
@@ -1795,8 +1799,6 @@
<string name="zen_mode_until" msgid="7336308492289875088">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g> വരെ"</string>
<string name="zen_mode_forever" msgid="4316804956488785559">"അവ്യക്തം"</string>
<string name="toolbar_collapse_description" msgid="2821479483960330739">"ചുരുക്കുക"</string>
- <!-- no translation found for zen_mode_next_alarm_summary (5915140424683747372) -->
- <skip />
- <!-- no translation found for zen_mode_next_alarm_line_one (5537042951553420916) -->
- <skip />
+ <string name="zen_mode_next_alarm_summary" msgid="5915140424683747372">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g>-നുള്ള അടുത്ത അലാറം വരെ"</string>
+ <string name="zen_mode_next_alarm_line_one" msgid="5537042951553420916">"അടുത്ത അലാറം വരെ"</string>
</resources>
diff --git a/core/res/res/values-mn-rMN/strings.xml b/core/res/res/values-mn-rMN/strings.xml
index 44974fd..4bd5d39 100644
--- a/core/res/res/values-mn-rMN/strings.xml
+++ b/core/res/res/values-mn-rMN/strings.xml
@@ -41,8 +41,6 @@
<string name="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g> сек"</string>
<string name="durationSecond" msgid="985669622276420331">"<xliff:g id="SECONDS">%1$d</xliff:g> сек"</string>
<string name="untitled" msgid="4638956954852782576">"<Гарчиггүй>"</string>
- <string name="ellipsis" msgid="7899829516048813237">"…"</string>
- <string name="ellipsis_two_dots" msgid="1228078994866030736">"‥"</string>
<string name="emptyPhoneNumber" msgid="7694063042079676517">"(Утасны дугаар байхгүй)"</string>
<string name="unknownName" msgid="2277556546742746522">"(Тодорхойгүй)"</string>
<string name="defaultVoiceMailAlphaTag" msgid="2660020990097733077">"дуут шуудан"</string>
@@ -415,6 +413,8 @@
<string name="permdesc_bindRemoteDisplay" msgid="1261242718727295981">"Эзэмшигчид алсын дэлгэц дэх дээд давхаргын интерфэйстэй холбогдох боломж олгоно. Энгийн апп-д шаардагдахгүй."</string>
<string name="permlab_bindRemoteViews" msgid="5697987759897367099">"виджет үйлчилгээтэй холбох"</string>
<string name="permdesc_bindRemoteViews" msgid="4717987810137692572">"Эзэмшигч нь виджет үйлчилгээний дээд-төвшиний интерфейстэй холбох боломжтой. Энгийн апп-д шаардлагагүй."</string>
+ <string name="permlab_bindRouteProvider" msgid="4869394607915096847">"маршрут нийлүүлэгчийн үйлчилгээтэй холбогдох"</string>
+ <string name="permdesc_bindRouteProvider" msgid="4703804520859960329">"Эзэмшигчид бүртгэгдсэн маршрут нийлүүлэгчтэй холбогдох боломж олгоно. Энгийн апп-уудад хэзээ ч шаардагдахгүй."</string>
<string name="permlab_bindDeviceAdmin" msgid="8704986163711455010">"төхөөрөмжийн админтай харилцан үйлчлэх"</string>
<string name="permdesc_bindDeviceAdmin" msgid="569715419543907930">"Эзэмшигч нь төхөөрөмжийн админруу интент илгээх боломжтой. Энгийн апп-д шаардлагагүй."</string>
<string name="permlab_bindTvInput" msgid="5601264742478168987">"ТВ оролт холбох"</string>
@@ -742,6 +742,8 @@
<string name="permdesc_bindNotificationListenerService" msgid="985697918576902986">"Эзэмшигч нь мэдэгдэл сонсох үйлчилгээний дээд-төвшиний интерфейстэй холбох боломжтой. Энгийн апп-д шаардлагагүй."</string>
<string name="permlab_bindConditionProviderService" msgid="1180107672332704641">"нөхцөл нийлүүлэгч үйлчилгээнд холбох"</string>
<string name="permdesc_bindConditionProviderService" msgid="1680513931165058425">"Эзэмшигчид нөхцөл нийлүүлэгч үйлчилгээний дээд-түвшний интерфейстэй холбох боломж олгоно. Энгийн апп-уудад хэзээ ч ашиглагдахгүй."</string>
+ <string name="permlab_bindMediaRouteService" msgid="6637740382272686835">"медиа маршрут үйлчилгээтэй холбох"</string>
+ <string name="permdesc_bindMediaRouteService" msgid="6436655024972496687">"Эзэмшигчид медиа маршрут үйлчилгээний дээр түвшний интерфэйст холбогдох боломж олгоно. Энгийн апп-д шаардагдахгүй."</string>
<string name="permlab_bindDreamService" msgid="4153646965978563462">"дрийм үйлчилгээнд холбох"</string>
<string name="permdesc_bindDreamService" msgid="7325825272223347863">"Эзэмшигч нь дрийм үйлчилгээний дээд-төвшиний интерфейстэй холбох боломжтой. Энгийн апп-д шаардлагагүй."</string>
<string name="permlab_invokeCarrierSetup" msgid="3699600833975117478">"үүрэн компанийн нийлүүлсэн тохируулгын апп-г өдөөх"</string>
@@ -1283,6 +1285,9 @@
<skip />
<string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"Wi-Fi-д холбогдож чадсангүй"</string>
<string name="wifi_watchdog_network_disabled_detailed" msgid="5548780776418332675">" Интернет холболт муу байна."</string>
+ <string name="wifi_connect_alert_title" msgid="8455846016001810172">"Холболтыг зөвшөөрөх үү?"</string>
+ <string name="wifi_connect_alert_message" msgid="8930084523889618078">"%1$s %2$s-тай холбогдохыг хүсэж байна"</string>
+ <string name="wifi_connect_default_application" msgid="7143109390475484319">"Аппликешн"</string>
<string name="wifi_p2p_dialog_title" msgid="97611782659324517">"Wi-Fi Шууд"</string>
<string name="wifi_p2p_turnon_message" msgid="2909250942299627244">"Wi-Fi Шуудыг эхлүүлнэ үү. Энэ нь Wi-Fi клиент/холболтын цэг унтраана."</string>
<string name="wifi_p2p_failed_message" msgid="3763669677935623084">"Wi-Fi Шуудыг эхлүүлж чадсангүй."</string>
diff --git a/core/res/res/values-mr-rIN/strings.xml b/core/res/res/values-mr-rIN/strings.xml
index 00cee9d..2b11519 100644
--- a/core/res/res/values-mr-rIN/strings.xml
+++ b/core/res/res/values-mr-rIN/strings.xml
@@ -41,8 +41,6 @@
<string name="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g> सेकंद"</string>
<string name="durationSecond" msgid="985669622276420331">"<xliff:g id="SECONDS">%1$d</xliff:g> सेकंद"</string>
<string name="untitled" msgid="4638956954852782576">"<अशीर्षकांकित>"</string>
- <string name="ellipsis" msgid="7899829516048813237">"…"</string>
- <string name="ellipsis_two_dots" msgid="1228078994866030736">"‥"</string>
<string name="emptyPhoneNumber" msgid="7694063042079676517">"(कोणताही फोन नंबर नाही)"</string>
<string name="unknownName" msgid="2277556546742746522">"(अज्ञात)"</string>
<string name="defaultVoiceMailAlphaTag" msgid="2660020990097733077">"व्हॉइसमेल"</string>
@@ -415,6 +413,8 @@
<string name="permdesc_bindRemoteDisplay" msgid="1261242718727295981">"होल्डरला दूरस्थ प्रदर्शनाच्या उच्च-दर्जाच्या इंटरफेसशी प्रतिबद्ध करण्याची अनुमती देते. सामान्य अॅप्ससाठी कधीही आवश्यक नसावे."</string>
<string name="permlab_bindRemoteViews" msgid="5697987759897367099">"विजेट सेवेवर प्रतिबद्ध व्हा"</string>
<string name="permdesc_bindRemoteViews" msgid="4717987810137692572">"विजेट सेवेचा शीर्ष-स्तर इंटरफेस प्रतिबद्ध करण्यासाठी होल्डरला अनुमती देते. सामान्य अॅप्सकरिता कधीही आवश्यक नसते."</string>
+ <string name="permlab_bindRouteProvider" msgid="4869394607915096847">"एका मार्ग प्रदाता सेवेवर प्रतिबद्ध करा"</string>
+ <string name="permdesc_bindRouteProvider" msgid="4703804520859960329">"कोणत्याही नोंदणीकृत मार्ग प्रदात्यांना प्रतिबद्ध करण्यासाठी होल्डरला अनुमती देते. सामान्य अॅप्सकरिता कधीही आवश्यकता नसते."</string>
<string name="permlab_bindDeviceAdmin" msgid="8704986163711455010">"डिव्हाइस प्रशासनाशी संवाद साधा"</string>
<string name="permdesc_bindDeviceAdmin" msgid="569715419543907930">"डिव्हाइस प्रशासकाकडे अभिप्राय पाठविण्यासाठी होल्डरला अनुमती देते. सामान्य अॅप्सकरिता कधीही आवश्यक नसते."</string>
<string name="permlab_bindTvInput" msgid="5601264742478168987">"एका टीव्ही इनपुटवर प्रतिबद्ध करा"</string>
@@ -742,6 +742,8 @@
<string name="permdesc_bindNotificationListenerService" msgid="985697918576902986">"होल्डरला सूचना ऐकणार्या सेवेच्या शीर्ष-दर्जाच्या इंटरफेसशी प्रतिबद्ध करण्याची अनुमती देते. सामान्य अॅप्ससाठी कधीही आवश्यक नसावे."</string>
<string name="permlab_bindConditionProviderService" msgid="1180107672332704641">"एका अट प्रदाता सेवेवर प्रतिबद्ध करा"</string>
<string name="permdesc_bindConditionProviderService" msgid="1680513931165058425">"स्थिती प्रदाता सेवेचा शीर्ष-स्तर इंटरफेस प्रतिबद्ध करण्यासाठी होल्डरला अनुमती देते. सामान्य अॅप्सकरिता कधीही आवश्यक नसते."</string>
+ <string name="permlab_bindMediaRouteService" msgid="6637740382272686835">"मीडिया मार्ग सेवेशी प्रतिबद्ध व्हा"</string>
+ <string name="permdesc_bindMediaRouteService" msgid="6436655024972496687">"मीडीया मार्ग सेवेच्या शीर्ष-दर्जाच्या इंटरफेसशी प्रतिबद्ध होण्यासाठी होल्डरला अनुमती द्या. सामान्य अॅप्ससाठी कधीही आवश्यकता नसावी."</string>
<string name="permlab_bindDreamService" msgid="4153646965978563462">"स्वप्न सेवेवर प्रतिबद्ध करा"</string>
<string name="permdesc_bindDreamService" msgid="7325825272223347863">"होल्डरला स्वप्नसेवेच्या शीर्ष-स्तराच्या इंटरफेसशी प्रतिबद्ध करण्यास अनुमती देते. सामान्य अॅप्सकरिता कधीही आवश्यक नसते."</string>
<string name="permlab_invokeCarrierSetup" msgid="3699600833975117478">"वाहकाद्वारे-प्रदान केलेल्या कॉन्फिगरेशन अॅपची विनंती करा"</string>
@@ -1283,6 +1285,9 @@
<skip />
<string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"वाय-फाय ला कनेक्ट करू शकलो नाही"</string>
<string name="wifi_watchdog_network_disabled_detailed" msgid="5548780776418332675">" खराब इंटरनेट कनेक्शन आहे."</string>
+ <string name="wifi_connect_alert_title" msgid="8455846016001810172">"कनेक्शनला अनुमती द्यायची?"</string>
+ <string name="wifi_connect_alert_message" msgid="8930084523889618078">"%1$s %2$s शी कनेक्ट करू इच्छितात"</string>
+ <string name="wifi_connect_default_application" msgid="7143109390475484319">"अनुप्रयोग"</string>
<string name="wifi_p2p_dialog_title" msgid="97611782659324517">"वाय-फाय थेट"</string>
<string name="wifi_p2p_turnon_message" msgid="2909250942299627244">"वाय-फाय थेट प्रारंभ करा. हे वाय-फाय क्लायंट/हॉटस्पॉट बंद करेल."</string>
<string name="wifi_p2p_failed_message" msgid="3763669677935623084">"वाय-फाय थेट प्रारंभ करू शकलो नाही."</string>
@@ -1776,8 +1781,7 @@
<string name="lock_to_app_unlock_password" msgid="6380979775916974414">"अनपिन करण्यापूर्वी संकेतशब्दासाठी विचारा"</string>
<string name="battery_saver_description" msgid="2510530476513605742">"बॅटरीचे आयुष्य सुधारण्यात मदत होण्यासाठी, बॅटरी बचतकर्ता आपल्या डिव्हाइसचे कार्यप्रदर्शन कमी करतो आणि कंपन आणि बराच पार्श्वभूमी डेटा मर्यादित करतो. संकालनावर अवलंबून असणारे ईमेल, संदेशन आणि अन्य अॅप्स आपण ते उघडल्याशिवाय अद्यतनित होऊ शकत नाहीत.\n\nआपले डिव्हाइस चार्ज होत असते तेव्हा बॅटरी बचतकर्ता स्वयंचलितपणे बंद होतो."</string>
<string name="downtime_condition_summary" msgid="8761776337475705749">"आपला कार्य न करण्याचा कालावधी <xliff:g id="FORMATTEDTIME">%1$s</xliff:g> वाजता समाप्त होईपर्यंत"</string>
- <!-- no translation found for downtime_condition_line_one (8762708714645352010) -->
- <skip />
+ <string name="downtime_condition_line_one" msgid="8762708714645352010">"आपला कार्य न करण्याचा कालावधी समाप्त होईपर्यंत"</string>
<plurals name="zen_mode_duration_minutes_summary">
<item quantity="one" msgid="3177683545388923234">"एका मिनिटासाठी (<xliff:g id="FORMATTEDTIME">%2$s</xliff:g> पर्यंत)"</item>
<item quantity="other" msgid="2787867221129368935">"%1$d मिनिटांसाठी (<xliff:g id="FORMATTEDTIME">%2$s</xliff:g> पर्यंत)"</item>
@@ -1797,8 +1801,6 @@
<string name="zen_mode_until" msgid="7336308492289875088">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g> पर्यंत"</string>
<string name="zen_mode_forever" msgid="4316804956488785559">"अनिश्चितपणे"</string>
<string name="toolbar_collapse_description" msgid="2821479483960330739">"संक्षिप्त करा"</string>
- <!-- no translation found for zen_mode_next_alarm_summary (5915140424683747372) -->
- <skip />
- <!-- no translation found for zen_mode_next_alarm_line_one (5537042951553420916) -->
- <skip />
+ <string name="zen_mode_next_alarm_summary" msgid="5915140424683747372">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g> वाजता पुढील अलार्मपर्यंत"</string>
+ <string name="zen_mode_next_alarm_line_one" msgid="5537042951553420916">"पुढील अलार्मपर्यंत"</string>
</resources>
diff --git a/core/res/res/values-ms-rMY/strings.xml b/core/res/res/values-ms-rMY/strings.xml
index 20433fa..e9012e8 100644
--- a/core/res/res/values-ms-rMY/strings.xml
+++ b/core/res/res/values-ms-rMY/strings.xml
@@ -41,8 +41,6 @@
<string name="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g> saat"</string>
<string name="durationSecond" msgid="985669622276420331">"<xliff:g id="SECONDS">%1$d</xliff:g> saat"</string>
<string name="untitled" msgid="4638956954852782576">"<Tidak bertajuk>"</string>
- <string name="ellipsis" msgid="7899829516048813237">"..."</string>
- <string name="ellipsis_two_dots" msgid="1228078994866030736">"‥"</string>
<string name="emptyPhoneNumber" msgid="7694063042079676517">"(Tiada nombor telefon)"</string>
<string name="unknownName" msgid="2277556546742746522">"(Tidak diketahui)"</string>
<string name="defaultVoiceMailAlphaTag" msgid="2660020990097733077">"Mel suara"</string>
@@ -415,6 +413,8 @@
<string name="permdesc_bindRemoteDisplay" msgid="1261242718727295981">"Membenarkan pemegang terikat dengan antara muka peringkat tertinggi bagi paparan jauh. Tidak sekali-kali diperlukan untuk apl biasa."</string>
<string name="permlab_bindRemoteViews" msgid="5697987759897367099">"terikat kepada perkhidmatan widget"</string>
<string name="permdesc_bindRemoteViews" msgid="4717987810137692572">"Membenarkan pemegang terikat dengan antara muka peringkat tertinggi bagi perkhidmatan widget. Tidak sekali-kali diperlukan untuk apl biasa."</string>
+ <string name="permlab_bindRouteProvider" msgid="4869394607915096847">"terikat kepada perkhidmatan pembekal laluan"</string>
+ <string name="permdesc_bindRouteProvider" msgid="4703804520859960329">"Membenarkan pemegang untuk terikat kepada mana-mana pembekal laluan yang berdaftar. Tidak sekali-kali diperlukan untuk apl normal."</string>
<string name="permlab_bindDeviceAdmin" msgid="8704986163711455010">"berinteraksi dengan pentadbir peranti"</string>
<string name="permdesc_bindDeviceAdmin" msgid="569715419543907930">"Membenarkan pemegang menghantar tujuan kepada pentadbir peranti. Tidak sekali-kali diperlukan untuk apl biasa."</string>
<string name="permlab_bindTvInput" msgid="5601264742478168987">"ikat kepada input TV"</string>
@@ -742,6 +742,8 @@
<string name="permdesc_bindNotificationListenerService" msgid="985697918576902986">"Membenarkan pemegang terikat dengan antara muka peringkat tertinggi bagi perkhidmatan pendengar pemberitahuan. Tidak sekali-kali diperlukan untuk apl biasa."</string>
<string name="permlab_bindConditionProviderService" msgid="1180107672332704641">"terikat kepada perkhidmatan pembekal keadaan"</string>
<string name="permdesc_bindConditionProviderService" msgid="1680513931165058425">"Membenarkan pemegang terikat dengan antara muka peringkat tertinggi bagi perkhidmatan pembekal keadaan. Tidak sekali-kali diperlukan untuk apl biasa."</string>
+ <string name="permlab_bindMediaRouteService" msgid="6637740382272686835">"terikat kepada perkhidmatan laluan media"</string>
+ <string name="permdesc_bindMediaRouteService" msgid="6436655024972496687">"Membenarkan pemegang terikat dengan antara muka peringkat tertinggi bagi perkhidmatan laluan media. Tidak sekali-kali diperlukan untuk apl biasa."</string>
<string name="permlab_bindDreamService" msgid="4153646965978563462">"terikat kepada perkhidmatan impian"</string>
<string name="permdesc_bindDreamService" msgid="7325825272223347863">"Membenarkan pemegang terikat dengan antara muka peringkat tertinggi bagi perkhidmatan impian. Tidak sekali-kali diperlukan untuk apl biasa."</string>
<string name="permlab_invokeCarrierSetup" msgid="3699600833975117478">"gunakan apl konfigurasi yang disediakan oleh pembawa"</string>
@@ -1283,6 +1285,9 @@
<skip />
<string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"Tidak boleh menyambung kepada Wi-Fi"</string>
<string name="wifi_watchdog_network_disabled_detailed" msgid="5548780776418332675">" mempunyai sambungan internet yang kurang baik."</string>
+ <string name="wifi_connect_alert_title" msgid="8455846016001810172">"Benarkan sambungan?"</string>
+ <string name="wifi_connect_alert_message" msgid="8930084523889618078">"%1$s ingin menyambung ke %2$s"</string>
+ <string name="wifi_connect_default_application" msgid="7143109390475484319">"Satu aplikasi"</string>
<string name="wifi_p2p_dialog_title" msgid="97611782659324517">"Wi-Fi Langsung"</string>
<string name="wifi_p2p_turnon_message" msgid="2909250942299627244">"Mulakan Wi-Fi Langsung. Hal ini akan mematikan pengendalian klien/liputan Wi-Fi."</string>
<string name="wifi_p2p_failed_message" msgid="3763669677935623084">"Tidak dapat memulakan Wi-Fi Langsung."</string>
diff --git a/core/res/res/values-my-rMM/strings.xml b/core/res/res/values-my-rMM/strings.xml
index b823344..39f0769 100644
--- a/core/res/res/values-my-rMM/strings.xml
+++ b/core/res/res/values-my-rMM/strings.xml
@@ -41,8 +41,6 @@
<string name="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g> စက္ကန့်"</string>
<string name="durationSecond" msgid="985669622276420331">"<xliff:g id="SECONDS">%1$d</xliff:g> စက္ကန့်"</string>
<string name="untitled" msgid="4638956954852782576">"<ခေါင်းစဉ်မဲ့>"</string>
- <string name="ellipsis" msgid="7899829516048813237">"…"</string>
- <string name="ellipsis_two_dots" msgid="1228078994866030736">"‥"</string>
<string name="emptyPhoneNumber" msgid="7694063042079676517">"(ဖုန်းနံပါတ်မရှိပါ)"</string>
<string name="unknownName" msgid="2277556546742746522">"အကြောင်းအရာ မသိရှိ"</string>
<string name="defaultVoiceMailAlphaTag" msgid="2660020990097733077">"အသံစာပို့စနစ်"</string>
@@ -415,6 +413,8 @@
<string name="permdesc_bindRemoteDisplay" msgid="1261242718727295981">"ဖုန်းကိုင်ထားသူနဲ့ ထိန်းချုပ်ပြသမှုမှ ထိပ်ပိုင်းအင်တာဖေ့စ် ကို ပူးပေါင်းခွင့်ပေးခြင်း။ ပုံမှန် အပလီကေးရှင်းများမှာ မလိုအပ်ပါ"</string>
<string name="permlab_bindRemoteViews" msgid="5697987759897367099">"ဝဒ်ဂျက်ဝန်ဆောင်မှုနှင့် ပူးပေါင်းရန်"</string>
<string name="permdesc_bindRemoteViews" msgid="4717987810137692572">"စွဲကိုင်ထားသူအားဝီဂျက် ဝန်ဆောင်မှု၏ ထိပ်သီး အဆင့် အင်တာဖေ့စ်သို့ ချိတ်တွဲခွင့်ကို ပေးသည်။ သာမန် appများ အတွက် ဘယ်တော့မှ မလိုအပ်နိုင်ပါ။"</string>
+ <string name="permlab_bindRouteProvider" msgid="4869394607915096847">"လမ်းကြောင်း စီမံပေးရေး ဝန်ဆောင်မှု တစ်ခုဆီသို့ ချိတ်တွဲခြင်း"</string>
+ <string name="permdesc_bindRouteProvider" msgid="4703804520859960329">"စွဲကိုင်ထားသူအား မှတ်ပုံတင်ထားသည့် လမ်းကြောင်း စီမံပေးသူ မည်သူနှင့်မဆို ချိတ်တွဲခွင့်ကို ပေးသည်။ သာမန် appများ အတွက် ဘယ်တော့မှ မလိုအပ်နိုင်ပါ။"</string>
<string name="permlab_bindDeviceAdmin" msgid="8704986163711455010">"စက်ပစ္စည်း ထိန်းချုပ်ခြင်းနှင့် တုံ့ပြန်မှု"</string>
<string name="permdesc_bindDeviceAdmin" msgid="569715419543907930">"စွဲကိုင်ထားသူအား ကိရိယာ စီမံအုပ်ချုပ်သူထံသို့ ရည်ရွယ်ချက်များကို ပို့ခွင့် ပေးသည်။ သာမန် appများ အတွက် ဘယ်တော့မှ မလိုအပ်နိုင်ပါ။"</string>
<string name="permlab_bindTvInput" msgid="5601264742478168987">"တီဗီ ထည့်သွင်းမှု တစ်ခုဆီသို့ ချိတ်တွဲပေးခြင်း"</string>
@@ -742,6 +742,8 @@
<string name="permdesc_bindNotificationListenerService" msgid="985697918576902986">"ဖုန်းကိုင်ထားသူနှင့် အကြောင်းကြားချက် နားစွင့်သော ဆားဗစ်မှ ထိပ်ပိုင်းအင်တာဖေ့စ် ကို ပူးပေါင်းခွင့်ပေးခြင်း။ ပုံမှန် အပလီကေးရှင်းများမှာ မလိုအပ်ပါ"</string>
<string name="permlab_bindConditionProviderService" msgid="1180107672332704641">"အခြေအနေ စီမံပေးရေး ဝန်ဆောင်မှု တစ်ခုဆီသို့ ချိတ်တွဲခြင်း"</string>
<string name="permdesc_bindConditionProviderService" msgid="1680513931165058425">"စွဲကိုင်ထားသူအား အခြေအနေကို စီမံပေးသူ၏ ထိပ်သီး အဆင့် အင်တာဖေ့စ်သို့ ချိတ်တွဲခွင့်ကို ပေးသည်။ သာမန် appများ အတွက် ဘယ်တော့မှ မလိုအပ်နိုင်ပါ။"</string>
+ <string name="permlab_bindMediaRouteService" msgid="6637740382272686835">"မီဒီယာ လမ်းကြောင်း ဝန်ဆောင်မှုသို့ တွဲချည်ရန်"</string>
+ <string name="permdesc_bindMediaRouteService" msgid="6436655024972496687">"ကိုင်ထားသူအား မီဒီယာ လမ်းကြောင်း ဝန်ဆောင်မှု၏ ထိပ်သီး အဆင့် အင်တာဖေ့စ်သို့ တွဲချည်ခွင့် ပြုသည်။ သာမန် appများ ဘယ်တော့မှ မလိုအပ်နိုင်ပါ။"</string>
<string name="permlab_bindDreamService" msgid="4153646965978563462">"အိပ်မက် ဝန်ဆောင်မှုသို့ ပေါင်းစည်းမည်"</string>
<string name="permdesc_bindDreamService" msgid="7325825272223347863">"အိမ်မက်ဝန်ဆောင်မှု၏ ထိပ်တန်းအဆင့် မျက်နှာပြင်အား ကိုင်ဆောင်သူမှ ပေါင်းစည်းရန် ခွင့်ပြုမည်။ သာမန် အပလီကေးရှင်းများတွင် မလိုအပ်ပါ။"</string>
<string name="permlab_invokeCarrierSetup" msgid="3699600833975117478">"မိုဘိုင်းဆက်သွယ်ရေးဝန်ဆောင်မှုဌာန မှ ထည့်သွင်းပေးသော အခြေအနေများအား ပယ်ဖျက်ခြင်း"</string>
@@ -1283,6 +1285,9 @@
<skip />
<string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"ဝိုင်ဖိုင်ကိုချိတ်ဆက်မရပါ"</string>
<string name="wifi_watchdog_network_disabled_detailed" msgid="5548780776418332675">" အင်တာနက် ဆက်သွယ်မှု ကောင်းကောင်းမရှိပါ"</string>
+ <string name="wifi_connect_alert_title" msgid="8455846016001810172">"ချိတ်ဆက်မှုကို ခွင့်ပြုမလား?"</string>
+ <string name="wifi_connect_alert_message" msgid="8930084523889618078">"%1$s က %2$s သို့ ချိတ်ဆက်ချင်"</string>
+ <string name="wifi_connect_default_application" msgid="7143109390475484319">"အပလီကေးရှင်း"</string>
<string name="wifi_p2p_dialog_title" msgid="97611782659324517">"တိုက်ရိုက် ဝိုင်ဖိုင်"</string>
<string name="wifi_p2p_turnon_message" msgid="2909250942299627244">"တိုက်ရိုက်ဝိုင်ဖိုင်ကို စတင်ပါ။ ၎င်းသည် ဝိုင်ဖိုင် ဟော့စပေါ့ကို ရပ်ဆိုင်းစေမှာ ဖြစ်ပါသည်။"</string>
<string name="wifi_p2p_failed_message" msgid="3763669677935623084">"တိုက်ရိုက်ဝိုင်ဖိုင်ကို စတင်လို့ မရပါ"</string>
diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml
index 415e8fe..8ecdc8f 100644
--- a/core/res/res/values-nb/strings.xml
+++ b/core/res/res/values-nb/strings.xml
@@ -41,8 +41,6 @@
<string name="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g> sek"</string>
<string name="durationSecond" msgid="985669622276420331">"<xliff:g id="SECONDS">%1$d</xliff:g> sek"</string>
<string name="untitled" msgid="4638956954852782576">"<Uten navn>"</string>
- <string name="ellipsis" msgid="7899829516048813237">"…"</string>
- <string name="ellipsis_two_dots" msgid="1228078994866030736">"‥"</string>
<string name="emptyPhoneNumber" msgid="7694063042079676517">"(Mangler telefonnummer)"</string>
<string name="unknownName" msgid="2277556546742746522">"(Ukjent)"</string>
<string name="defaultVoiceMailAlphaTag" msgid="2660020990097733077">"Telefonsvarer"</string>
@@ -415,6 +413,8 @@
<string name="permdesc_bindRemoteDisplay" msgid="1261242718727295981">"Lar innehaveren binde seg til det øverste grensesnittnivået for ekstern skjerm. Skal aldri være nødvendig for vanlige apper."</string>
<string name="permlab_bindRemoteViews" msgid="5697987759897367099">"binde til modultjenste"</string>
<string name="permdesc_bindRemoteViews" msgid="4717987810137692572">"Lar innehaveren binde seg til det øverste nivået av grensesnittet for en modultjeneste. Skal aldri være nødvendig for vanlige apper."</string>
+ <string name="permlab_bindRouteProvider" msgid="4869394607915096847">"binde seg til en ruteleverandørtjeneste"</string>
+ <string name="permdesc_bindRouteProvider" msgid="4703804520859960329">"Innehaveren av tillatelsen kan binde seg til ruteleverandører. Dette er ikke nødvendig for vanlige apper."</string>
<string name="permlab_bindDeviceAdmin" msgid="8704986163711455010">"kommunisere med enhetsadministrator"</string>
<string name="permdesc_bindDeviceAdmin" msgid="569715419543907930">"Lar innehaveren sende hensikter til en enhetsadministrator. Skal aldri være nødvendig for normale apper."</string>
<string name="permlab_bindTvInput" msgid="5601264742478168987">"binde appen til en TV-inngang"</string>
@@ -742,6 +742,8 @@
<string name="permdesc_bindNotificationListenerService" msgid="985697918576902986">"Lar innehaveren binde seg til det øverste grensesnittnivået for en varsellyttertjeneste. Skal aldri være nødvendig for vanlige apper."</string>
<string name="permlab_bindConditionProviderService" msgid="1180107672332704641">"binde seg til en leverandørtjeneste for betingelser"</string>
<string name="permdesc_bindConditionProviderService" msgid="1680513931165058425">"Gir innehaveren tillatelse til å binde til toppnivået av brukergrensesnittet for en leverandørtjeneste for betingelser. Dette skal ikke være nødvendig for vanlige apper."</string>
+ <string name="permlab_bindMediaRouteService" msgid="6637740382272686835">"binde seg til en mediarutingstjeneste"</string>
+ <string name="permdesc_bindMediaRouteService" msgid="6436655024972496687">"Gir innehaveren tillatelse til å binde til øverste nivå av grensesnittet for en tjeneste som bruker mediaruting. Dette skal ikke være nødvendig for vanlige apper."</string>
<string name="permlab_bindDreamService" msgid="4153646965978563462">"binde til en drømmetjeneste"</string>
<string name="permdesc_bindDreamService" msgid="7325825272223347863">"Tillater eieren å binde seg til det øverste nivået av grensesnittet til en drømmetjeneste. Kreves aldri for vanlige apper."</string>
<string name="permlab_invokeCarrierSetup" msgid="3699600833975117478">"starte konfigurasjonsappen som ble levert av operatøren"</string>
@@ -1283,6 +1285,9 @@
<skip />
<string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"Kan ikke koble til Wi-Fi"</string>
<string name="wifi_watchdog_network_disabled_detailed" msgid="5548780776418332675">" har en dårlig Internett-tilkobling."</string>
+ <string name="wifi_connect_alert_title" msgid="8455846016001810172">"Vil du tillat tilkoblingen?"</string>
+ <string name="wifi_connect_alert_message" msgid="8930084523889618078">"%1$s prøver å koble til %2$s"</string>
+ <string name="wifi_connect_default_application" msgid="7143109390475484319">"En app"</string>
<string name="wifi_p2p_dialog_title" msgid="97611782659324517">"Wi-Fi Direct"</string>
<string name="wifi_p2p_turnon_message" msgid="2909250942299627244">"Start Wi-Fi Direct. Dette deaktiverer Wi-Fi-klienten/-sonen."</string>
<string name="wifi_p2p_failed_message" msgid="3763669677935623084">"Kunne ikke starte Wi-Fi Direct."</string>
diff --git a/core/res/res/values-ne-rNP/strings.xml b/core/res/res/values-ne-rNP/strings.xml
index 177cf06..b474dff 100644
--- a/core/res/res/values-ne-rNP/strings.xml
+++ b/core/res/res/values-ne-rNP/strings.xml
@@ -41,8 +41,6 @@
<string name="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g> सेकेन्ड"</string>
<string name="durationSecond" msgid="985669622276420331">"<xliff:g id="SECONDS">%1$d</xliff:g> सेकेन्ड"</string>
<string name="untitled" msgid="4638956954852782576">"<बिना शीर्षक>"</string>
- <string name="ellipsis" msgid="7899829516048813237">"…"</string>
- <string name="ellipsis_two_dots" msgid="1228078994866030736">"‥"</string>
<string name="emptyPhoneNumber" msgid="7694063042079676517">"(कुनै फोन नम्बर छैन)"</string>
<string name="unknownName" msgid="2277556546742746522">"(अज्ञात)"</string>
<string name="defaultVoiceMailAlphaTag" msgid="2660020990097733077">"भ्वाइस मेल"</string>
@@ -415,6 +413,8 @@
<string name="permdesc_bindRemoteDisplay" msgid="1261242718727295981">"ताररहित प्रदर्शनको उच्च स्तरको इन्टरफेसलाई पक्का गर्न सम्पर्क राख्ने अनुमति दिन्छ। साधारण अनुप्रयोगहरूलाई कहिल्यै आवश्यक पर्दैन।"</string>
<string name="permlab_bindRemoteViews" msgid="5697987759897367099">"एउटा विजेट सेवासँग संगठित हुनुहोस्"</string>
<string name="permdesc_bindRemoteViews" msgid="4717987810137692572">"एउटा विजेट सेवाको उच्च स्तरको इन्टरफेसलाई पक्का गर्नको लागि समाती राख्नेलाई अनुमति दिन्छ। साधारण अनुप्रयोगहरूलाई कहिल्यै आवश्यक पर्ने छैन।"</string>
+ <string name="permlab_bindRouteProvider" msgid="4869394607915096847">"मार्ग प्रदाय सेवा बाँध्छ"</string>
+ <string name="permdesc_bindRouteProvider" msgid="4703804520859960329">"होल्डरलाई कुनै पनि दर्ता मार्ग प्रदायहरूमा बाँध्न अनुमति दिन्छ। साधारण अनुप्रयोगहरूको लागि कहिल्यै पनि आवश्यक पर्दैन।"</string>
<string name="permlab_bindDeviceAdmin" msgid="8704986163711455010">"उपकरणको प्रबन्धसँग अन्तरक्रिया गर्नुहोस्"</string>
<string name="permdesc_bindDeviceAdmin" msgid="569715419543907930">"उपकरण प्रशासक लाई आशय पठाउन समाती राख्नेलाई अनुमति दिन्छ। साधारण अनुप्रयोहरूको लागि कहिल्यै पनी आवश्यक पर्दैन।"</string>
<string name="permlab_bindTvInput" msgid="5601264742478168987">"टिभि निवेशलाई आबद्ध"</string>
@@ -742,6 +742,8 @@
<string name="permdesc_bindNotificationListenerService" msgid="985697918576902986">"होल्डरलाई सूचना श्रोता सेवाको शीर्ष-स्तरको इन्टरफेस बाँध्न अनुमति दिन्छ। सामान्य अनुप्रयोगहरूलाई कहिले पनि आवश्यक नपर्न सक्दछ।"</string>
<string name="permlab_bindConditionProviderService" msgid="1180107672332704641">"सर्त प्रदायक सेवामा जोड्न"</string>
<string name="permdesc_bindConditionProviderService" msgid="1680513931165058425">"सर्त प्रदायक सेवाको माथिल्लो स्तरको इन्टरफेसमा जोड्न बाहकलाई अनुमति दिन्छ। साधारण अनुप्रयोगहरूको लागि कहिल्यै पनि आवश्यक पर्दैन।"</string>
+ <string name="permlab_bindMediaRouteService" msgid="6637740382272686835">"मिडिया मार्ग सेवासँग बाँध्नुहोस्"</string>
+ <string name="permdesc_bindMediaRouteService" msgid="6436655024972496687">"होल्डरलाई मिडिया मार्ग सेवाको शीर्ष तह इन्टरफेस बाध्ने गर्न अनुमति दिन्छ। साधारण अनुप्रयोगहरूको लागि कहिल्यै पनि आवश्यक पर्दैन।"</string>
<string name="permlab_bindDreamService" msgid="4153646965978563462">"सपना सेवामा बाँध्नुहोस्"</string>
<string name="permdesc_bindDreamService" msgid="7325825272223347863">"होल्डरलाई सपना सेवाको माथिल्लो स्तरको इन्टरफेसमा बाँध्न अनुमति दिन्छ। साधारण अनुप्रयोगहरूको लागि कहिल्यै पनि आवश्यक पर्दैन।"</string>
<string name="permlab_invokeCarrierSetup" msgid="3699600833975117478">"वाहक-प्रदान विन्यास अनुप्रयोग सुरु गर्नुहोस्"</string>
@@ -1291,6 +1293,9 @@
<skip />
<string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"वाइ-फाइसँग जडान गर्न सकेन"</string>
<string name="wifi_watchdog_network_disabled_detailed" msgid="5548780776418332675">" कमजोर इन्टरनेट जडान छ।"</string>
+ <string name="wifi_connect_alert_title" msgid="8455846016001810172">"जडान अनुमति दिने हो?"</string>
+ <string name="wifi_connect_alert_message" msgid="8930084523889618078">"%1$s ले %2$s मा जडान गर्न चाहन्छ"</string>
+ <string name="wifi_connect_default_application" msgid="7143109390475484319">"एउटा अनुप्रयोग"</string>
<string name="wifi_p2p_dialog_title" msgid="97611782659324517">"वाइफाइ प्रत्यक्ष"</string>
<string name="wifi_p2p_turnon_message" msgid="2909250942299627244">"वाइफाइ सिधा सुरु गर्नुहोस्। यसले वाइफाइ ग्राहक/हट्स्पटलाई बन्द गराउने छ।"</string>
<string name="wifi_p2p_failed_message" msgid="3763669677935623084">"वाइफाइ सिधा सुरु हुन सकेन।"</string>
diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml
index 0f126d0..e5c8315 100644
--- a/core/res/res/values-nl/strings.xml
+++ b/core/res/res/values-nl/strings.xml
@@ -41,8 +41,6 @@
<string name="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g> seconden"</string>
<string name="durationSecond" msgid="985669622276420331">"<xliff:g id="SECONDS">%1$d</xliff:g> seconde"</string>
<string name="untitled" msgid="4638956954852782576">"<Zonder titel>"</string>
- <string name="ellipsis" msgid="7899829516048813237">"…"</string>
- <string name="ellipsis_two_dots" msgid="1228078994866030736">"‥"</string>
<string name="emptyPhoneNumber" msgid="7694063042079676517">"(Geen telefoonnummer)"</string>
<string name="unknownName" msgid="2277556546742746522">"(Onbekend)"</string>
<string name="defaultVoiceMailAlphaTag" msgid="2660020990097733077">"Voicemail"</string>
@@ -415,6 +413,8 @@
<string name="permdesc_bindRemoteDisplay" msgid="1261242718727295981">"Hiermee wordt de houder toegestaan verbinding te maken met de hoofdinterface van een extern display. Nooit vereist voor normale apps."</string>
<string name="permlab_bindRemoteViews" msgid="5697987759897367099">"verbinden met een widgetservice"</string>
<string name="permdesc_bindRemoteViews" msgid="4717987810137692572">"Hiermee wordt de houder toegestaan verbinding te maken met de hoofdinterface van een widgetservice. Nooit vereist voor normale apps."</string>
+ <string name="permlab_bindRouteProvider" msgid="4869394607915096847">"binden aan de service van een routeprovider"</string>
+ <string name="permdesc_bindRouteProvider" msgid="4703804520859960329">"Hiermee kan de houder binden aan geregistreerde routeproviders. Nooit gebruikt voor normale apps."</string>
<string name="permlab_bindDeviceAdmin" msgid="8704986163711455010">"interactie met apparaatbeheer"</string>
<string name="permdesc_bindDeviceAdmin" msgid="569715419543907930">"Hiermee kan de houder intenties verzenden naar een apparaatbeheerder. Nooit vereist voor normale apps."</string>
<string name="permlab_bindTvInput" msgid="5601264742478168987">"binden aan een tv-ingang"</string>
@@ -742,6 +742,8 @@
<string name="permdesc_bindNotificationListenerService" msgid="985697918576902986">"Hiermee kan de houder koppelen aan de hoofdinterface van een listener-service voor meldingen. Nooit vereist voor normale apps."</string>
<string name="permlab_bindConditionProviderService" msgid="1180107672332704641">"binden aan de service van een provider van voorwaarden"</string>
<string name="permdesc_bindConditionProviderService" msgid="1680513931165058425">"Hiermee kan de houder binden aan de hoofdinterface van de service van een provider van voorwaarden. Nooit vereist voor normale apps."</string>
+ <string name="permlab_bindMediaRouteService" msgid="6637740382272686835">"binden aan een service voor mediaroutering"</string>
+ <string name="permdesc_bindMediaRouteService" msgid="6436655024972496687">"Hiermee kan de houder binden aan de hoofdinterface van een service voor mediaroutering. Nooit vereist voor normale apps."</string>
<string name="permlab_bindDreamService" msgid="4153646965978563462">"verbinding maken met een droomservice"</string>
<string name="permdesc_bindDreamService" msgid="7325825272223347863">"Hiermee wordt de houder toegestaan verbinding te maken met de hoofdinterface van een droomservice. Nooit vereist voor normale apps."</string>
<string name="permlab_invokeCarrierSetup" msgid="3699600833975117478">"de door de provider geleverde configuratie-app aanroepen"</string>
@@ -1283,6 +1285,9 @@
<skip />
<string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"Kan geen verbinding maken met wifi"</string>
<string name="wifi_watchdog_network_disabled_detailed" msgid="5548780776418332675">" heeft een slechte internetverbinding."</string>
+ <string name="wifi_connect_alert_title" msgid="8455846016001810172">"Verbinding toestaan?"</string>
+ <string name="wifi_connect_alert_message" msgid="8930084523889618078">"%1$s wilt verbinding maken met %2$s"</string>
+ <string name="wifi_connect_default_application" msgid="7143109390475484319">"Een app"</string>
<string name="wifi_p2p_dialog_title" msgid="97611782659324517">"Wifi Direct"</string>
<string name="wifi_p2p_turnon_message" msgid="2909250942299627244">"Wifi Direct starten. Hierdoor wordt de wifi-client/hotspot uitgeschakeld."</string>
<string name="wifi_p2p_failed_message" msgid="3763669677935623084">"Kan Wifi Direct niet starten."</string>
@@ -1776,8 +1781,7 @@
<string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Vragen om wachtwoord voordat items worden losgemaakt"</string>
<string name="battery_saver_description" msgid="2510530476513605742">"Accubesparing beperkt de prestaties van uw apparaat, de trilfunctie en de meeste achtergrondgegevens om de accuduur te verlengen. Uw e-mail, online berichten en andere apps die gebruik maken van synchronisatie worden niet geüpdatet totdat u deze opent.\n\nAccubesparing wordt automatisch uitgeschakeld wanneer uw apparaat wordt opgeladen."</string>
<string name="downtime_condition_summary" msgid="8761776337475705749">"Totdat uw downtime eindigt om <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
- <!-- no translation found for downtime_condition_line_one (8762708714645352010) -->
- <skip />
+ <string name="downtime_condition_line_one" msgid="8762708714645352010">"Tot uw downtime afloopt"</string>
<plurals name="zen_mode_duration_minutes_summary">
<item quantity="one" msgid="3177683545388923234">"Eén minuut (tot <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
<item quantity="other" msgid="2787867221129368935">"%1$d minuten (tot <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
@@ -1797,8 +1801,6 @@
<string name="zen_mode_until" msgid="7336308492289875088">"Tot <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
<string name="zen_mode_forever" msgid="4316804956488785559">"Voor onbepaalde tijd"</string>
<string name="toolbar_collapse_description" msgid="2821479483960330739">"Samenvouwen"</string>
- <!-- no translation found for zen_mode_next_alarm_summary (5915140424683747372) -->
- <skip />
- <!-- no translation found for zen_mode_next_alarm_line_one (5537042951553420916) -->
- <skip />
+ <string name="zen_mode_next_alarm_summary" msgid="5915140424683747372">"Tot het volgende alarm om <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
+ <string name="zen_mode_next_alarm_line_one" msgid="5537042951553420916">"Tot het volgende alarm"</string>
</resources>
diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml
index d81f0f0..3f2e238 100644
--- a/core/res/res/values-pl/strings.xml
+++ b/core/res/res/values-pl/strings.xml
@@ -41,8 +41,6 @@
<string name="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g> s"</string>
<string name="durationSecond" msgid="985669622276420331">"<xliff:g id="SECONDS">%1$d</xliff:g> s"</string>
<string name="untitled" msgid="4638956954852782576">"<Bez nazwy>"</string>
- <string name="ellipsis" msgid="7899829516048813237">"…"</string>
- <string name="ellipsis_two_dots" msgid="1228078994866030736">"‥"</string>
<string name="emptyPhoneNumber" msgid="7694063042079676517">"(Brak numeru telefonu)"</string>
<string name="unknownName" msgid="2277556546742746522">"(Nieznany)"</string>
<string name="defaultVoiceMailAlphaTag" msgid="2660020990097733077">"Poczta głosowa"</string>
@@ -415,6 +413,8 @@
<string name="permdesc_bindRemoteDisplay" msgid="1261242718727295981">"Zezwala na tworzenie powiązania z interfejsem najwyższego poziomu wyświetlacza zdalnego. Nieprzeznaczone dla zwykłych aplikacji."</string>
<string name="permlab_bindRemoteViews" msgid="5697987759897367099">"powiązanie z usługą widżetów"</string>
<string name="permdesc_bindRemoteViews" msgid="4717987810137692572">"Zezwala na tworzenie powiązania z interfejsem najwyższego poziomu usługi widżetów. Nie powinno być nigdy potrzebne w przypadku zwykłych aplikacji."</string>
+ <string name="permlab_bindRouteProvider" msgid="4869394607915096847">"powiązanie z usługą dostawcy tras"</string>
+ <string name="permdesc_bindRouteProvider" msgid="4703804520859960329">"Umożliwia właścicielowi powiązanie z dowolnymi zarejestrowanymi dostawcami tras. Nie powinno być nigdy potrzebne w normalnych aplikacjach."</string>
<string name="permlab_bindDeviceAdmin" msgid="8704986163711455010">"interakcja z administratorem urządzenia"</string>
<string name="permdesc_bindDeviceAdmin" msgid="569715419543907930">"Zezwala na wysyłanie intencji do administratora urządzenia. Nie powinno być nigdy potrzebne w przypadku zwykłych aplikacji."</string>
<string name="permlab_bindTvInput" msgid="5601264742478168987">"powiązanie z wejściem TV"</string>
@@ -742,6 +742,8 @@
<string name="permdesc_bindNotificationListenerService" msgid="985697918576902986">"Zezwala na tworzenie powiązania z interfejsem najwyższego poziomu usługi odbiornika powiadomień. Nie powinno być nigdy potrzebne dla zwykłych aplikacji."</string>
<string name="permlab_bindConditionProviderService" msgid="1180107672332704641">"powiąż z usługą dostawcy warunków"</string>
<string name="permdesc_bindConditionProviderService" msgid="1680513931165058425">"Zezwala na tworzenie powiązania z interfejsem najwyższego poziomu usługi dostawcy warunków. Nieprzeznaczone dla zwykłych aplikacji."</string>
+ <string name="permlab_bindMediaRouteService" msgid="6637740382272686835">"powiązanie z usługą kierowania multimediów"</string>
+ <string name="permdesc_bindMediaRouteService" msgid="6436655024972496687">"Zezwala na tworzenie powiązania z interfejsem najwyższego poziomu usługi kierowania multimediów. Nieprzeznaczone dla zwykłych aplikacji."</string>
<string name="permlab_bindDreamService" msgid="4153646965978563462">"powiąż z usługą wygaszacza ekranu"</string>
<string name="permdesc_bindDreamService" msgid="7325825272223347863">"Zezwala na tworzenie powiązania z interfejsem najwyższego poziomu usługi wygaszacza ekranu. Nie powinno być nigdy potrzebne dla zwykłych aplikacji."</string>
<string name="permlab_invokeCarrierSetup" msgid="3699600833975117478">"wywoływanie aplikacji konfiguracyjnej udostępnionej przez operatora"</string>
@@ -1283,6 +1285,9 @@
<skip />
<string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"Nie można połączyć się z siecią Wi-Fi."</string>
<string name="wifi_watchdog_network_disabled_detailed" msgid="5548780776418332675">" ma powolne połączenie internetowe."</string>
+ <string name="wifi_connect_alert_title" msgid="8455846016001810172">"Zezwolić na połączenie?"</string>
+ <string name="wifi_connect_alert_message" msgid="8930084523889618078">"%1$s chce połączyć się z: %2$s"</string>
+ <string name="wifi_connect_default_application" msgid="7143109390475484319">"Aplikacja"</string>
<string name="wifi_p2p_dialog_title" msgid="97611782659324517">"Wi-Fi Direct"</string>
<string name="wifi_p2p_turnon_message" msgid="2909250942299627244">"Uruchom Wi-Fi Direct. Spowoduje to wyłączenie klienta lub punktu dostępu Wi-Fi."</string>
<string name="wifi_p2p_failed_message" msgid="3763669677935623084">"Nie można uruchomić Wi-Fi Direct."</string>
diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml
index 7df167b..65ffa4a 100644
--- a/core/res/res/values-pt-rPT/strings.xml
+++ b/core/res/res/values-pt-rPT/strings.xml
@@ -41,8 +41,6 @@
<string name="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g> seg"</string>
<string name="durationSecond" msgid="985669622276420331">"<xliff:g id="SECONDS">%1$d</xliff:g> seg"</string>
<string name="untitled" msgid="4638956954852782576">"<Sem nome>"</string>
- <string name="ellipsis" msgid="7899829516048813237">"…"</string>
- <string name="ellipsis_two_dots" msgid="1228078994866030736">"‥"</string>
<string name="emptyPhoneNumber" msgid="7694063042079676517">"(Nenhum número de telefone)"</string>
<string name="unknownName" msgid="2277556546742746522">"(Desconhecido)"</string>
<string name="defaultVoiceMailAlphaTag" msgid="2660020990097733077">"Correio de voz"</string>
@@ -415,6 +413,8 @@
<string name="permdesc_bindRemoteDisplay" msgid="1261242718727295981">"Permite ao detentor associar a interface de nível superior a um ecrã remoto. Nunca deve ser necessário para aplicações normais."</string>
<string name="permlab_bindRemoteViews" msgid="5697987759897367099">"vincular a um serviço de widget"</string>
<string name="permdesc_bindRemoteViews" msgid="4717987810137692572">"Permite que o titular vincule a interface de nível superior de um serviço de widget. Nunca deverá ser necessário para aplicações normais."</string>
+ <string name="permlab_bindRouteProvider" msgid="4869394607915096847">"vincular a serviço de fornecedor de trajeto"</string>
+ <string name="permdesc_bindRouteProvider" msgid="4703804520859960329">"Permite ao titular vincular a quaisquer fornecedores de trajeto registado. Nunca deverá ser necessário para aplicações normais."</string>
<string name="permlab_bindDeviceAdmin" msgid="8704986163711455010">"interagir com um administrador do dispositivo"</string>
<string name="permdesc_bindDeviceAdmin" msgid="569715419543907930">"Permite ao titular enviar intenções para um administrador do aparelho. Nunca deverá ser necessário para aplicações normais."</string>
<string name="permlab_bindTvInput" msgid="5601264742478168987">"vincular a uma entrada de TV"</string>
@@ -742,6 +742,8 @@
<string name="permdesc_bindNotificationListenerService" msgid="985697918576902986">"Permite que o titular vincule a interface de nível superior de um serviço de escuta de notificações. Nunca deverá ser necessário para aplicações normais."</string>
<string name="permlab_bindConditionProviderService" msgid="1180107672332704641">"vincular a um serviço de fornecedor de condição"</string>
<string name="permdesc_bindConditionProviderService" msgid="1680513931165058425">"Permite que o titular vincule a interface de nível superior de um serviço de fornecedor de condição. Nunca deverá ser necessário para aplicações normais."</string>
+ <string name="permlab_bindMediaRouteService" msgid="6637740382272686835">"vincular a um serviço de encaminhamento multimédia"</string>
+ <string name="permdesc_bindMediaRouteService" msgid="6436655024972496687">"Permite que o titular vincule a interface de nível superior de um serviço de encaminhamento multimédia. Nunca deverá ser necessário para aplicações normais."</string>
<string name="permlab_bindDreamService" msgid="4153646965978563462">"vincular-se a um serviço de sonho"</string>
<string name="permdesc_bindDreamService" msgid="7325825272223347863">"Permite ao detentor ficar vinculado à interface de nível superior de um serviço de sonho. Nunca deverá ser necessário para aplicações normais."</string>
<string name="permlab_invokeCarrierSetup" msgid="3699600833975117478">"invocar a aplicação de configuração fornecida pela operadora"</string>
@@ -1283,6 +1285,9 @@
<skip />
<string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"Não foi possível ligar a Wi-Fi"</string>
<string name="wifi_watchdog_network_disabled_detailed" msgid="5548780776418332675">" tem uma ligação à internet fraca."</string>
+ <string name="wifi_connect_alert_title" msgid="8455846016001810172">"Permitir ligação?"</string>
+ <string name="wifi_connect_alert_message" msgid="8930084523889618078">"%1$s pretende ligar a %2$s"</string>
+ <string name="wifi_connect_default_application" msgid="7143109390475484319">"Uma aplicação"</string>
<string name="wifi_p2p_dialog_title" msgid="97611782659324517">"Wi-Fi Direct"</string>
<string name="wifi_p2p_turnon_message" msgid="2909250942299627244">"Iniciar o Wi-Fi Direct. Esta opção desativará o cliente/zona Wi-Fi."</string>
<string name="wifi_p2p_failed_message" msgid="3763669677935623084">"Não foi possível iniciar o Wi-Fi Direct."</string>
@@ -1776,8 +1781,7 @@
<string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Pedir palavra-passe antes de soltar"</string>
<string name="battery_saver_description" msgid="2510530476513605742">"Para ajudar a melhorar a duração da bateria, a poupança de bateria reduz o desempenho do dispositivo e limita a vibração e a maior parte dos dados de segundo plano. O email, as mensagens e outras aplicações que dependem da sincronização não podem ser atualizados, exceto se os abrir.\n\nA poupança de bateria desliga-se automaticamente quando o dispositivo estiver a carregar."</string>
<string name="downtime_condition_summary" msgid="8761776337475705749">"Até o período de inatividade terminar às <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
- <!-- no translation found for downtime_condition_line_one (8762708714645352010) -->
- <skip />
+ <string name="downtime_condition_line_one" msgid="8762708714645352010">"Até terminar o período de inatividade"</string>
<plurals name="zen_mode_duration_minutes_summary">
<item quantity="one" msgid="3177683545388923234">"Durante um minuto (até às <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
<item quantity="other" msgid="2787867221129368935">"Durante %1$d minutos (até às <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
@@ -1797,8 +1801,6 @@
<string name="zen_mode_until" msgid="7336308492289875088">"Até às <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
<string name="zen_mode_forever" msgid="4316804956488785559">"Indefinidamente"</string>
<string name="toolbar_collapse_description" msgid="2821479483960330739">"Reduzir"</string>
- <!-- no translation found for zen_mode_next_alarm_summary (5915140424683747372) -->
- <skip />
- <!-- no translation found for zen_mode_next_alarm_line_one (5537042951553420916) -->
- <skip />
+ <string name="zen_mode_next_alarm_summary" msgid="5915140424683747372">"Até ao próximo alarme, às <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
+ <string name="zen_mode_next_alarm_line_one" msgid="5537042951553420916">"Até ao próximo alarme"</string>
</resources>
diff --git a/core/res/res/values-pt/strings.xml b/core/res/res/values-pt/strings.xml
index 34caf99..6b4f735 100644
--- a/core/res/res/values-pt/strings.xml
+++ b/core/res/res/values-pt/strings.xml
@@ -41,8 +41,6 @@
<string name="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g> s"</string>
<string name="durationSecond" msgid="985669622276420331">"<xliff:g id="SECONDS">%1$d</xliff:g> s"</string>
<string name="untitled" msgid="4638956954852782576">"<Sem título>"</string>
- <string name="ellipsis" msgid="7899829516048813237">"…"</string>
- <string name="ellipsis_two_dots" msgid="1228078994866030736">".."</string>
<string name="emptyPhoneNumber" msgid="7694063042079676517">"(Nenhum número de telefone)"</string>
<string name="unknownName" msgid="2277556546742746522">"(Desconhecido)"</string>
<string name="defaultVoiceMailAlphaTag" msgid="2660020990097733077">"Correio de voz"</string>
@@ -415,6 +413,8 @@
<string name="permdesc_bindRemoteDisplay" msgid="1261242718727295981">"Permite que o proprietário use a interface de nível superior de uma tela remota. Não deve ser necessário para apps comuns."</string>
<string name="permlab_bindRemoteViews" msgid="5697987759897367099">"sujeitar-se a um serviço de widget"</string>
<string name="permdesc_bindRemoteViews" msgid="4717987810137692572">"Permite que o proprietário utilize a interface de nível superior de um serviço de widget. Nunca deve ser necessário para apps normais."</string>
+ <string name="permlab_bindRouteProvider" msgid="4869394607915096847">"usar um serviço provedor de rotas"</string>
+ <string name="permdesc_bindRouteProvider" msgid="4703804520859960329">"Permite que o proprietário use qualquer provedor de rotas registrado. Não deve ser necessário para apps comuns."</string>
<string name="permlab_bindDeviceAdmin" msgid="8704986163711455010">"interagir com o administrador de um dispositivo"</string>
<string name="permdesc_bindDeviceAdmin" msgid="569715419543907930">"Permite que o proprietário envie tentativas ao administrador de um aparelho. Nunca deve ser necessário para apps normais."</string>
<string name="permlab_bindTvInput" msgid="5601264742478168987">"associar a uma entrada de TV"</string>
@@ -746,6 +746,8 @@
<string name="permdesc_bindNotificationListenerService" msgid="985697918576902986">"Permite que o proprietário sujeite a interface de nível superior a um serviço ouvinte de notificações. Não deve ser necessário para apps comuns."</string>
<string name="permlab_bindConditionProviderService" msgid="1180107672332704641">"associar a um serviço provedor de condições"</string>
<string name="permdesc_bindConditionProviderService" msgid="1680513931165058425">"Permite que o proprietário use a interface de nível superior de um serviço provedor de condições. Não deve ser necessário para apps comuns."</string>
+ <string name="permlab_bindMediaRouteService" msgid="6637740382272686835">"usar serviço de roteamento de mídia"</string>
+ <string name="permdesc_bindMediaRouteService" msgid="6436655024972496687">"Permite que o proprietário use a interface de nível superior de um serviço de roteamento de mídia. Não deve ser necessário para apps comuns."</string>
<string name="permlab_bindDreamService" msgid="4153646965978563462">"conectar-se a um serviço de sonho"</string>
<string name="permdesc_bindDreamService" msgid="7325825272223347863">"Permite que o sistema autorizado se conecte à interface de nível superior de um serviço de sonho. Não deve ser necessário para apps comuns."</string>
<string name="permlab_invokeCarrierSetup" msgid="3699600833975117478">"invocar o app de configuração fornecido pela operadora"</string>
@@ -1288,6 +1290,9 @@
<skip />
<string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"Não foi possível se conectar a redes Wi-Fi"</string>
<string name="wifi_watchdog_network_disabled_detailed" msgid="5548780776418332675">" tem uma conexão de baixa qualidade com a Internet."</string>
+ <string name="wifi_connect_alert_title" msgid="8455846016001810172">"Permitir conexão?"</string>
+ <string name="wifi_connect_alert_message" msgid="8930084523889618078">"%1$s gostaria de se conectar a %2$s"</string>
+ <string name="wifi_connect_default_application" msgid="7143109390475484319">"Um app"</string>
<string name="wifi_p2p_dialog_title" msgid="97611782659324517">"Wi-Fi Direct"</string>
<string name="wifi_p2p_turnon_message" msgid="2909250942299627244">"Iniciar o Wi-Fi Direct. Isso desativará o ponto de acesso/cliente Wi-Fi."</string>
<string name="wifi_p2p_failed_message" msgid="3763669677935623084">"Não foi possível iniciar o Wi-Fi Direct."</string>
@@ -1781,12 +1786,15 @@
<string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Pedir senha antes de liberar"</string>
<string name="battery_saver_description" msgid="2510530476513605742">"Para ajudar a melhorar a vida útil da bateria, a economia de bateria reduz o desempenho do dispositivo e restringe a vibração e a maioria dos dados em segundo plano. É possível que apps de e-mail, mensagens, entre outros que dependem de sincronização não sejam atualizados a menos que sejam abertos.\n\nA economia de bateria é desativada automaticamente quando o dispositivo estiver carregando."</string>
<string name="downtime_condition_summary" msgid="8761776337475705749">"Até o período de inatividade terminar às <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
- <!-- no translation found for downtime_condition_line_one (8762708714645352010) -->
- <skip />
- <!-- no translation found for zen_mode_duration_minutes_summary:one (3177683545388923234) -->
- <!-- no translation found for zen_mode_duration_minutes_summary:other (2787867221129368935) -->
- <!-- no translation found for zen_mode_duration_hours_summary:one (597194865053253679) -->
- <!-- no translation found for zen_mode_duration_hours_summary:other (2827214920627669898) -->
+ <string name="downtime_condition_line_one" msgid="8762708714645352010">"Até que seu tempo de inatividade termine"</string>
+ <plurals name="zen_mode_duration_minutes_summary">
+ <item quantity="one" msgid="3177683545388923234">"Por um minuto (até às <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
+ <item quantity="other" msgid="2787867221129368935">"Por %1$d minutos (até às <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
+ </plurals>
+ <plurals name="zen_mode_duration_hours_summary">
+ <item quantity="one" msgid="597194865053253679">"Por uma hora (até às <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
+ <item quantity="other" msgid="2827214920627669898">"Por %1$d horas (até às <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
+ </plurals>
<plurals name="zen_mode_duration_minutes">
<item quantity="one" msgid="9040808414992812341">"Por 1 minuto"</item>
<item quantity="other" msgid="6924190729213550991">"Por %d minutos"</item>
@@ -1795,13 +1803,10 @@
<item quantity="one" msgid="3480040795582254384">"Por 1 hora"</item>
<item quantity="other" msgid="5408537517529822157">"Por %d horas"</item>
</plurals>
- <!-- no translation found for zen_mode_until (7336308492289875088) -->
- <skip />
+ <string name="zen_mode_until" msgid="7336308492289875088">"Até às <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
<string name="zen_mode_forever" msgid="4316804956488785559">"Indefinidamente"</string>
<!-- no translation found for toolbar_collapse_description (2821479483960330739) -->
<skip />
- <!-- no translation found for zen_mode_next_alarm_summary (5915140424683747372) -->
- <skip />
- <!-- no translation found for zen_mode_next_alarm_line_one (5537042951553420916) -->
- <skip />
+ <string name="zen_mode_next_alarm_summary" msgid="5915140424683747372">"Até o próximo alarme em <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
+ <string name="zen_mode_next_alarm_line_one" msgid="5537042951553420916">"Até o próximo alarme"</string>
</resources>
diff --git a/core/res/res/values-ro/strings.xml b/core/res/res/values-ro/strings.xml
index 5f47938..f954bd5 100644
--- a/core/res/res/values-ro/strings.xml
+++ b/core/res/res/values-ro/strings.xml
@@ -41,8 +41,6 @@
<string name="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g> sec"</string>
<string name="durationSecond" msgid="985669622276420331">"<xliff:g id="SECONDS">%1$d</xliff:g> sec"</string>
<string name="untitled" msgid="4638956954852782576">"<Fără titlu>"</string>
- <string name="ellipsis" msgid="7899829516048813237">"…"</string>
- <string name="ellipsis_two_dots" msgid="1228078994866030736">"‥"</string>
<string name="emptyPhoneNumber" msgid="7694063042079676517">"(Niciun număr de telefon)"</string>
<string name="unknownName" msgid="2277556546742746522">"(Necunoscut)"</string>
<string name="defaultVoiceMailAlphaTag" msgid="2660020990097733077">"Mesaj vocal"</string>
@@ -415,6 +413,8 @@
<string name="permdesc_bindRemoteDisplay" msgid="1261242718727295981">"Permite proprietarului să se conecteze la interfața de nivel superior a unui ecran la distanță. Nu ar trebui să fie niciodată necesară pentru aplicațiile obișnuite."</string>
<string name="permlab_bindRemoteViews" msgid="5697987759897367099">"conectare la un serviciu widget"</string>
<string name="permdesc_bindRemoteViews" msgid="4717987810137692572">"Permite proprietarului să se conecteze la interfaţa de nivel superior a unui serviciu widget. Nu ar trebui să fie niciodată necesară pentru aplicaţiile obişnuite."</string>
+ <string name="permlab_bindRouteProvider" msgid="4869394607915096847">"se conectează la un serviciu de furnizare a traseelor"</string>
+ <string name="permdesc_bindRouteProvider" msgid="4703804520859960329">"Permite titularului să se conecteze la furnizorii de trasee înregistrați. Nu este necesară pentru aplicațiile obișnuite."</string>
<string name="permlab_bindDeviceAdmin" msgid="8704986163711455010">"interacţionare cu administratorul unui dispozitiv"</string>
<string name="permdesc_bindDeviceAdmin" msgid="569715419543907930">"Permite proprietarului să trimită intenţii către un administrator al dispozitivului. Nu ar trebui să fie niciodată necesară pentru aplicaţiile obişnuite."</string>
<string name="permlab_bindTvInput" msgid="5601264742478168987">"se conectează la o intrare TV"</string>
@@ -742,6 +742,8 @@
<string name="permdesc_bindNotificationListenerService" msgid="985697918576902986">"Permite proprietarului să se conecteze la interfața de nivel superior a unui serviciu de citire a notificărilor. În mod normal aplicațiile nu ar trebui să aibă nevoie de această permisiune."</string>
<string name="permlab_bindConditionProviderService" msgid="1180107672332704641">"conectare la un serviciu furnizor de condiții"</string>
<string name="permdesc_bindConditionProviderService" msgid="1680513931165058425">"Permite proprietarului să se conecteze la interfața de nivel superior a unui serviciu furnizor de condiții. Nu ar trebui să fie necesară pentru aplicațiile obișnuite."</string>
+ <string name="permlab_bindMediaRouteService" msgid="6637740382272686835">"se conectează la un serviciu de trasee multimedia"</string>
+ <string name="permdesc_bindMediaRouteService" msgid="6436655024972496687">"Permite deținătorului să se conecteze la interfața de nivel superior a unui serviciu de trasee multimedia. Nu ar trebui să fie necesară pentru aplicațiile obișnuite."</string>
<string name="permlab_bindDreamService" msgid="4153646965978563462">"se conectează la un serviciu de vis"</string>
<string name="permdesc_bindDreamService" msgid="7325825272223347863">"Permite deținătorului să se conecteze la interfața superioară a unui serviciu de vis. Această opțiune nu ar trebui să fie necesară pentru aplicațiile obișnuite."</string>
<string name="permlab_invokeCarrierSetup" msgid="3699600833975117478">"apelarea aplicației de configurare furnizată de operator"</string>
@@ -1283,6 +1285,9 @@
<skip />
<string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"Nu se poate conecta la Wi-Fi"</string>
<string name="wifi_watchdog_network_disabled_detailed" msgid="5548780776418332675">" are o conexiune la internet slabă."</string>
+ <string name="wifi_connect_alert_title" msgid="8455846016001810172">"Permiteți conectarea?"</string>
+ <string name="wifi_connect_alert_message" msgid="8930084523889618078">"%1$s dorește să se conecteze la %2$s"</string>
+ <string name="wifi_connect_default_application" msgid="7143109390475484319">"O aplicație"</string>
<string name="wifi_p2p_dialog_title" msgid="97611782659324517">"Wi-Fi Direct"</string>
<string name="wifi_p2p_turnon_message" msgid="2909250942299627244">"Porniţi Wi-Fi Direct. Acest lucru va dezactiva clientul/hotspotul Wi-Fi."</string>
<string name="wifi_p2p_failed_message" msgid="3763669677935623084">"Wi-Fi Direct nu a putut porni."</string>
diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml
index 7ee4604..628b763 100644
--- a/core/res/res/values-ru/strings.xml
+++ b/core/res/res/values-ru/strings.xml
@@ -41,8 +41,6 @@
<string name="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g> с"</string>
<string name="durationSecond" msgid="985669622276420331">"<xliff:g id="SECONDS">%1$d</xliff:g> с"</string>
<string name="untitled" msgid="4638956954852782576">"<Без названия>"</string>
- <string name="ellipsis" msgid="7899829516048813237">"…"</string>
- <string name="ellipsis_two_dots" msgid="1228078994866030736">"..."</string>
<string name="emptyPhoneNumber" msgid="7694063042079676517">"(Нет номера телефона)"</string>
<string name="unknownName" msgid="2277556546742746522">"(Неизвестно)"</string>
<string name="defaultVoiceMailAlphaTag" msgid="2660020990097733077">"Голосовая почта"</string>
@@ -415,6 +413,8 @@
<string name="permdesc_bindRemoteDisplay" msgid="1261242718727295981">"Приложение сможет подключаться к базовому интерфейсу удаленного дисплея. Это разрешение обычно используется только специальными приложениями."</string>
<string name="permlab_bindRemoteViews" msgid="5697987759897367099">"Подключение к службе виджетов"</string>
<string name="permdesc_bindRemoteViews" msgid="4717987810137692572">"Приложение сможет подключаться к базовому интерфейсу службы виджетов. Это разрешение не используется обычными приложениями."</string>
+ <string name="permlab_bindRouteProvider" msgid="4869394607915096847">"Подключение к серверам поставщиков маршрутов"</string>
+ <string name="permdesc_bindRouteProvider" msgid="4703804520859960329">"Приложение сможет подключаться к серверам зарегистрированных поставщиков маршрутов. Это разрешение не используется обычными приложениями."</string>
<string name="permlab_bindDeviceAdmin" msgid="8704986163711455010">"Взаимодействие с администратором устройства"</string>
<string name="permdesc_bindDeviceAdmin" msgid="569715419543907930">"Приложение сможет отправлять объекты intent администратору устройства. Это разрешение не используется обычными приложениями."</string>
<string name="permlab_bindTvInput" msgid="5601264742478168987">"Подключение к ТВ-входу"</string>
@@ -742,6 +742,8 @@
<string name="permdesc_bindNotificationListenerService" msgid="985697918576902986">"Приложение сможет подключаться к базовому интерфейсу службы просмотра уведомлений. Это разрешение не используется обычными приложениями."</string>
<string name="permlab_bindConditionProviderService" msgid="1180107672332704641">"Подключение к серверам поставщиков условий"</string>
<string name="permdesc_bindConditionProviderService" msgid="1680513931165058425">"Приложение сможет подключаться к базовому интерфейсу поставщиков условий. Это разрешение обычно используется только специальными приложениями."</string>
+ <string name="permlab_bindMediaRouteService" msgid="6637740382272686835">"Привязка к средству передачи медиафайлов"</string>
+ <string name="permdesc_bindMediaRouteService" msgid="6436655024972496687">"Привязка к интерфейсу верхнего уровня средства передачи медиафайлов. Не требуется для работы обычных приложений."</string>
<string name="permlab_bindDreamService" msgid="4153646965978563462">"Подключение к службе экранных заставок"</string>
<string name="permdesc_bindDreamService" msgid="7325825272223347863">"Подключение к базовому интерфейсу службы экранных заставок. Это разрешение не используется обычными приложениями."</string>
<string name="permlab_invokeCarrierSetup" msgid="3699600833975117478">"Запуск приложения настроек, предоставленного оператором"</string>
@@ -1283,6 +1285,9 @@
<skip />
<string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"Не удалось подключиться к сети Wi-Fi"</string>
<string name="wifi_watchdog_network_disabled_detailed" msgid="5548780776418332675">" – плохое интернет-соединение."</string>
+ <string name="wifi_connect_alert_title" msgid="8455846016001810172">"Разрешить подключение?"</string>
+ <string name="wifi_connect_alert_message" msgid="8930084523889618078">"%1$s запрашивает доступ на подключение к %2$s."</string>
+ <string name="wifi_connect_default_application" msgid="7143109390475484319">"Приложение"</string>
<string name="wifi_p2p_dialog_title" msgid="97611782659324517">"Wi-Fi Direct"</string>
<string name="wifi_p2p_turnon_message" msgid="2909250942299627244">"Начать соединение через Wi-Fi Direct. Модуль Wi-Fi будет отключен."</string>
<string name="wifi_p2p_failed_message" msgid="3763669677935623084">"Не удалось запустить Wi-Fi Direct."</string>
diff --git a/core/res/res/values-si-rLK/strings.xml b/core/res/res/values-si-rLK/strings.xml
index d686a64..eb51487 100644
--- a/core/res/res/values-si-rLK/strings.xml
+++ b/core/res/res/values-si-rLK/strings.xml
@@ -41,8 +41,6 @@
<string name="durationSeconds" msgid="8050088505238241405">"තත් <xliff:g id="SECONDS">%1$d</xliff:g>"</string>
<string name="durationSecond" msgid="985669622276420331">"තත් <xliff:g id="SECONDS">%1$d</xliff:g>"</string>
<string name="untitled" msgid="4638956954852782576">"<නම් යොදා නැත>"</string>
- <string name="ellipsis" msgid="7899829516048813237">"…"</string>
- <string name="ellipsis_two_dots" msgid="1228078994866030736">"‥"</string>
<string name="emptyPhoneNumber" msgid="7694063042079676517">"(දුරකථන අංකයක් නොමැත)"</string>
<string name="unknownName" msgid="2277556546742746522">"(නොදනී)"</string>
<string name="defaultVoiceMailAlphaTag" msgid="2660020990097733077">"කටහඬ තැපෑල"</string>
@@ -415,6 +413,8 @@
<string name="permdesc_bindRemoteDisplay" msgid="1261242718727295981">"දූරස්ථ දර්ශනය ඉහල මට්ටමේ අතුරු මුහුණතක් වෙත සම්බන්ධ කිරීමට ධාරකයාට අවසර දෙන්න. සාමාන්ය යෙදුම්වලට කිසි විටෙක අවශ්ය නොවෙයි."</string>
<string name="permlab_bindRemoteViews" msgid="5697987759897367099">"විජට සේවාවකට බඳින්න"</string>
<string name="permdesc_bindRemoteViews" msgid="4717987810137692572">"විජට් සේවාව ඉහල මට්ටමේ අතුරු මුහුණතක් වෙත සම්බන්ධ කිරීමට ධාරකයාට අවසර දෙන්න. සාමාන්ය යෙදුම්වලට කිසි විටෙක අවශ්ය නොවෙයි."</string>
+ <string name="permlab_bindRouteProvider" msgid="4869394607915096847">"මාර්ග ප්රතිපාදකගේ සේවාව බඳින්න"</string>
+ <string name="permdesc_bindRouteProvider" msgid="4703804520859960329">"ඕනෑම ලියාපදිංචි කළ මාර්ග ප්රතිපාදකයන්ට බඳින්න ධාරකයාට අනුමත කරන්න. සාමාන්ය යෙදුම් සඳහා කිසිදා අවශ්ය නොවෙයි."</string>
<string name="permlab_bindDeviceAdmin" msgid="8704986163711455010">"උපාංග පරිපාලක සමඟ අන්තර්ක්රියාකාරී වීම"</string>
<string name="permdesc_bindDeviceAdmin" msgid="569715419543907930">"උපාංග පාලකයා වෙතට අභිප්රායයන් යැවීමට ධාරකයාට අවසර දෙන්න. සාමාන්ය යෙදුම්වලට කිසි විටෙක අවශ්ය නොවෙයි."</string>
<string name="permlab_bindTvInput" msgid="5601264742478168987">"TV ආදානයක් වෙතට බඳින්න"</string>
@@ -746,6 +746,8 @@
<string name="permdesc_bindNotificationListenerService" msgid="985697918576902986">"දැනුම්දීම් අසන්නාගේ සේවාවේ ඉහළ මට්ටමේ අතුරුමුහුණතට බැඳීමට දරන්නාට අවසර දේ. සාමාන්ය යෙදුම් සඳහා කිසිසේත් අවශ්ය නොවේ."</string>
<string name="permlab_bindConditionProviderService" msgid="1180107672332704641">"තත්ත්වය සපයන්නාගේ සේවාවට බඳින්න"</string>
<string name="permdesc_bindConditionProviderService" msgid="1680513931165058425">"තත්ත්වය සපයන්නාගේ සේවාවට ඉහළ-මට්ටමේ අතුරු මුහුණතක් බැඳිමට ධාරකයාට අවසර දෙන්න. සාමාන්ය යෙදුම් සඳහා කවදාවත් අවශ්යය නොවෙයි."</string>
+ <string name="permlab_bindMediaRouteService" msgid="6637740382272686835">"මාධ්ය ගමන් කරන සේවාව බඳින්න"</string>
+ <string name="permdesc_bindMediaRouteService" msgid="6436655024972496687">"මාධ්ය ගමන් කරන සේවාවට ඉහළ-මට්ටමේ අතුරු මුහුණතක් බැඳිමට ධාරකයාට අවසර දෙන්න. සාමාන්ය යෙදුම් සඳහා කවදාවත් අවශ්යය නොවෙයි."</string>
<string name="permlab_bindDreamService" msgid="4153646965978563462">"ඩ්රීම් සේවාවකට බැඳීම"</string>
<string name="permdesc_bindDreamService" msgid="7325825272223347863">"ඩ්රීම් සේවාව ඉහල මට්ටමේ අතුරු මුහුණතක් වෙත සම්බන්ධ කිරීමට ධාරකයාට අවසර දෙන්න. සාමාන්ය යෙදුම්වලට කිසි විටෙක අවශ්ය නොවෙයි."</string>
<string name="permlab_invokeCarrierSetup" msgid="3699600833975117478">"වාහකය සැපයු වින්යාසය යෙදුම ඉල්ලා සිටින්න"</string>
@@ -1289,6 +1291,9 @@
<skip />
<string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"Wi-Fi වෙත සම්බන්ධ විය නොහැක"</string>
<string name="wifi_watchdog_network_disabled_detailed" msgid="5548780776418332675">" දුබල අන්තර්ජාල සම්බන්ධතාවයක් ඇත."</string>
+ <string name="wifi_connect_alert_title" msgid="8455846016001810172">"සම්බන්ධතාවයට ඉඩ දෙන්නද?"</string>
+ <string name="wifi_connect_alert_message" msgid="8930084523889618078">"%2$s වෙත සම්බන්ධවීමට %1$s කැමතිය"</string>
+ <string name="wifi_connect_default_application" msgid="7143109390475484319">"යෙදුම"</string>
<string name="wifi_p2p_dialog_title" msgid="97611782659324517">"ඍජු Wi-Fi"</string>
<string name="wifi_p2p_turnon_message" msgid="2909250942299627244">"ඍජු Wi-Fi ආරම්භ කරන්න. මෙය Wi-Fi සේවාදායක/හොට්ස්පොට් එක අක්රිය කරනු ඇත."</string>
<string name="wifi_p2p_failed_message" msgid="3763669677935623084">"ඍජු Wi-Fi ආරම්භ කළ නොහැක."</string>
diff --git a/core/res/res/values-sk/strings.xml b/core/res/res/values-sk/strings.xml
index a8c31eb..67c1665 100644
--- a/core/res/res/values-sk/strings.xml
+++ b/core/res/res/values-sk/strings.xml
@@ -41,8 +41,6 @@
<string name="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g> s"</string>
<string name="durationSecond" msgid="985669622276420331">"<xliff:g id="SECONDS">%1$d</xliff:g> s"</string>
<string name="untitled" msgid="4638956954852782576">"<Bez mena>"</string>
- <string name="ellipsis" msgid="7899829516048813237">"…"</string>
- <string name="ellipsis_two_dots" msgid="1228078994866030736">"‥"</string>
<string name="emptyPhoneNumber" msgid="7694063042079676517">"(žiadne telefónne číslo)"</string>
<string name="unknownName" msgid="2277556546742746522">"(Neznáme)"</string>
<string name="defaultVoiceMailAlphaTag" msgid="2660020990097733077">"Hlasová schránka"</string>
@@ -415,6 +413,8 @@
<string name="permdesc_bindRemoteDisplay" msgid="1261242718727295981">"Umožňuje držiteľovi viazať sa na najvyššiu úroveň rozhrania vzdialeného displeja. Bežné aplikácie by toto nastavenie nemali nikdy potrebovať."</string>
<string name="permlab_bindRemoteViews" msgid="5697987759897367099">"viazať sa k službe miniaplikácie"</string>
<string name="permdesc_bindRemoteViews" msgid="4717987810137692572">"Umožňuje držiteľovi viazať sa na najvyššiu úroveň rozhrania služby miniaplikácií. Bežné aplikácie by toto nastavenie nemali nikdy potrebovať."</string>
+ <string name="permlab_bindRouteProvider" msgid="4869394607915096847">"viazanie na službu poskytovateľa cesty"</string>
+ <string name="permdesc_bindRouteProvider" msgid="4703804520859960329">"Umožňuje držiteľovi viazať sa na akýchkoľvek registrovaných poskytovateľov cesty. Normálne aplikácie by toto povolenie nemali nikdy nepotrebovať."</string>
<string name="permlab_bindDeviceAdmin" msgid="8704986163711455010">"komunikovať so správcom zariadenia"</string>
<string name="permdesc_bindDeviceAdmin" msgid="569715419543907930">"Umožňuje držiteľovi odosielať informácie správcovi zariadenia. Bežné aplikácie by toto nastavenie nemali nikdy potrebovať."</string>
<string name="permlab_bindTvInput" msgid="5601264742478168987">"viazanie na televízny vstup"</string>
@@ -742,6 +742,8 @@
<string name="permdesc_bindNotificationListenerService" msgid="985697918576902986">"Umožňuje držiteľovi naviazať sa na najvyššiu úroveň služby na počúvanie upozornení. Bežné aplikácie by toto nastavenie nemali nikdy požadovať."</string>
<string name="permlab_bindConditionProviderService" msgid="1180107672332704641">"viazanie na službu poskytovateľa podmienky"</string>
<string name="permdesc_bindConditionProviderService" msgid="1680513931165058425">"Umožňuje držiteľovi viazať sa na najvyššiu úroveň rozhrania služby poskytovateľa podmienky. Bežné aplikácie by toto povolenie nemali nikdy potrebovať."</string>
+ <string name="permlab_bindMediaRouteService" msgid="6637740382272686835">"viazanie na službu smerovania médií"</string>
+ <string name="permdesc_bindMediaRouteService" msgid="6436655024972496687">"Umožňuje držiteľovi viazať sa na najvyššiu úroveň rozhrania služby smerovania médií. Bežné aplikácie by toto povolenie nemali nikdy potrebovať."</string>
<string name="permlab_bindDreamService" msgid="4153646965978563462">"viazať sa so službou Dream service"</string>
<string name="permdesc_bindDreamService" msgid="7325825272223347863">"Umožňuje držiteľovi viazať sa na najvyššiu úroveň rozhrania služby Dream service. Bežné aplikácie by toto povolenie nemali nikdy potrebovať."</string>
<string name="permlab_invokeCarrierSetup" msgid="3699600833975117478">"vyvolanie aplikácie pre konfiguráciu poskytnutú operátorom"</string>
@@ -1283,6 +1285,9 @@
<skip />
<string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"Nepodarilo sa pripojiť k sieti Wi-Fi"</string>
<string name="wifi_watchdog_network_disabled_detailed" msgid="5548780776418332675">" má nekvalitné internetové pripojenie."</string>
+ <string name="wifi_connect_alert_title" msgid="8455846016001810172">"Povoliť pripojenie?"</string>
+ <string name="wifi_connect_alert_message" msgid="8930084523889618078">"Zariadenie %1$s sa chce pripojiť k sieti %2$s"</string>
+ <string name="wifi_connect_default_application" msgid="7143109390475484319">"Aplikácia"</string>
<string name="wifi_p2p_dialog_title" msgid="97611782659324517">"Priame pripojenie Wi-Fi"</string>
<string name="wifi_p2p_turnon_message" msgid="2909250942299627244">"Spustiť priame pripojenie siete Wi-Fi. Táto možnosť vypne sieť Wi-Fi v režime klient alebo hotspot."</string>
<string name="wifi_p2p_failed_message" msgid="3763669677935623084">"Priame pripojenie siete Wi-Fi sa nepodarilo spustiť"</string>
diff --git a/core/res/res/values-sl/strings.xml b/core/res/res/values-sl/strings.xml
index 246de04..f7c0e8a 100644
--- a/core/res/res/values-sl/strings.xml
+++ b/core/res/res/values-sl/strings.xml
@@ -41,8 +41,6 @@
<string name="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g> s"</string>
<string name="durationSecond" msgid="985669622276420331">"<xliff:g id="SECONDS">%1$d</xliff:g> s"</string>
<string name="untitled" msgid="4638956954852782576">"<Brez naslova>"</string>
- <string name="ellipsis" msgid="7899829516048813237">"…"</string>
- <string name="ellipsis_two_dots" msgid="1228078994866030736">"‥"</string>
<string name="emptyPhoneNumber" msgid="7694063042079676517">"(Ni telefonske številke)"</string>
<string name="unknownName" msgid="2277556546742746522">"(Neznano)"</string>
<string name="defaultVoiceMailAlphaTag" msgid="2660020990097733077">"Glasovna pošta"</string>
@@ -415,6 +413,8 @@
<string name="permdesc_bindRemoteDisplay" msgid="1261242718727295981">"Imetniku omogoča povezovanje z vmesnikom oddaljenega prikaza najvišje ravni. Tega ni treba nikoli uporabiti za navadne aplikacije."</string>
<string name="permlab_bindRemoteViews" msgid="5697987759897367099">"poveži s storitvijo pripomočka"</string>
<string name="permdesc_bindRemoteViews" msgid="4717987810137692572">"Lastniku omogoča povezovanje z vmesnikom storitve pripomočka najvišje ravni. Tega ni treba nikoli uporabiti za navadne aplikacije."</string>
+ <string name="permlab_bindRouteProvider" msgid="4869394607915096847">"Povezava s storitvijo ponudnika poti"</string>
+ <string name="permdesc_bindRouteProvider" msgid="4703804520859960329">"Omogoča imetniku, da se povezuje z registriranimi ponudniki poti. Tega ni treba nikoli uporabiti za navadne aplikacije."</string>
<string name="permlab_bindDeviceAdmin" msgid="8704986163711455010">"interakcija s skrbnikom naprave"</string>
<string name="permdesc_bindDeviceAdmin" msgid="569715419543907930">"Omogoča lastniku, da pošlje namere skrbniku naprave. Nikoli se ne uporablja za navadne aplikacije."</string>
<string name="permlab_bindTvInput" msgid="5601264742478168987">"povezava s TV-vhodom"</string>
@@ -742,6 +742,8 @@
<string name="permdesc_bindNotificationListenerService" msgid="985697918576902986">"Lastniku omogoča povezovanje z vmesnikom storitve poslušalca obvestil najvišje ravni. Tega nikoli ni treba uporabiti za navadne aplikacije."</string>
<string name="permlab_bindConditionProviderService" msgid="1180107672332704641">"povezovanje s storitvijo ponudnika pogojev"</string>
<string name="permdesc_bindConditionProviderService" msgid="1680513931165058425">"Imetniku omogoča povezovanje z vmesnikom storitve ponudnika pogojev najvišje ravni. Tega ni treba nikoli uporabiti za navadne aplikacije."</string>
+ <string name="permlab_bindMediaRouteService" msgid="6637740382272686835">"povezovanje s storitvijo poti predstavnosti"</string>
+ <string name="permdesc_bindMediaRouteService" msgid="6436655024972496687">"Imetniku omogoča povezovanje z vmesnikom storitve poti predstavnosti najvišje ravni. Tega ni treba nikoli uporabiti za navadne aplikacije."</string>
<string name="permlab_bindDreamService" msgid="4153646965978563462">"povezava s storitvijo sanjarjenja"</string>
<string name="permdesc_bindDreamService" msgid="7325825272223347863">"Imetniku omogoča povezovanje z vmesnikom storitve sanjarjenja najvišje ravni. Tega ni treba nikoli uporabiti za navadne aplikacije."</string>
<string name="permlab_invokeCarrierSetup" msgid="3699600833975117478">"sprožitev operaterjeve aplikacije za konfiguracijo"</string>
@@ -1283,6 +1285,9 @@
<skip />
<string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"Z omrežjem Wi-Fi se ni mogoče povezati"</string>
<string name="wifi_watchdog_network_disabled_detailed" msgid="5548780776418332675">" ima slabo internetno povezavo."</string>
+ <string name="wifi_connect_alert_title" msgid="8455846016001810172">"Ali dovolite vzpostavitev povezave?"</string>
+ <string name="wifi_connect_alert_message" msgid="8930084523889618078">"%1$s želi vzpostaviti povezavo s tem: %2$s"</string>
+ <string name="wifi_connect_default_application" msgid="7143109390475484319">"Aplikacija"</string>
<string name="wifi_p2p_dialog_title" msgid="97611782659324517">"Wi-Fi Direct"</string>
<string name="wifi_p2p_turnon_message" msgid="2909250942299627244">"Zaženite Wi-Fi Direct. S tem boste izklopili odjemalca/dostopno točko Wi-Fi."</string>
<string name="wifi_p2p_failed_message" msgid="3763669677935623084">"Wi-Fi Direct ni bilo mogoče zagnati."</string>
diff --git a/core/res/res/values-sr/strings.xml b/core/res/res/values-sr/strings.xml
index e554734..483f9c1 100644
--- a/core/res/res/values-sr/strings.xml
+++ b/core/res/res/values-sr/strings.xml
@@ -41,8 +41,6 @@
<string name="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g> сек"</string>
<string name="durationSecond" msgid="985669622276420331">"<xliff:g id="SECONDS">%1$d</xliff:g> сек"</string>
<string name="untitled" msgid="4638956954852782576">"<Без наслова>"</string>
- <string name="ellipsis" msgid="7899829516048813237">"…"</string>
- <string name="ellipsis_two_dots" msgid="1228078994866030736">"‥"</string>
<string name="emptyPhoneNumber" msgid="7694063042079676517">"(Нема броја телефона)"</string>
<string name="unknownName" msgid="2277556546742746522">"(Непознато)"</string>
<string name="defaultVoiceMailAlphaTag" msgid="2660020990097733077">"Гласовна пошта"</string>
@@ -415,6 +413,8 @@
<string name="permdesc_bindRemoteDisplay" msgid="1261242718727295981">"Дозвољава власнику да се повеже са интерфејсом удаљеног екрана највишег нивоа. Уобичајене апликације никада не би требало да је користе."</string>
<string name="permlab_bindRemoteViews" msgid="5697987759897367099">"обавезивање на услугу виџета"</string>
<string name="permdesc_bindRemoteViews" msgid="4717987810137692572">"Дозвољава власнику да се обавеже на интерфејс услуге виџета највишег нивоа. Уобичајене апликације никада не би требало да је користе."</string>
+ <string name="permlab_bindRouteProvider" msgid="4869394607915096847">"повежи са услугом добављача путања"</string>
+ <string name="permdesc_bindRouteProvider" msgid="4703804520859960329">"Дозвољава власнику да се повеже са добављачима путања. Никада не би требало да буде потребно за обичне апликације."</string>
<string name="permlab_bindDeviceAdmin" msgid="8704986163711455010">"интеракција са администратором уређаја"</string>
<string name="permdesc_bindDeviceAdmin" msgid="569715419543907930">"Омогућава да власник шаље своје намере администратору уређаја. Уобичајене апликације никада не би требало да је користе."</string>
<string name="permlab_bindTvInput" msgid="5601264742478168987">"повезивање са ТВ улазом"</string>
@@ -742,6 +742,8 @@
<string name="permdesc_bindNotificationListenerService" msgid="985697918576902986">"Дозвољава власнику да се повеже са интерфејсом услуге монитора обавештења највишег нивоа. Уобичајене апликације никада не би требало да је користе."</string>
<string name="permlab_bindConditionProviderService" msgid="1180107672332704641">"повежи са услугом добављача услова"</string>
<string name="permdesc_bindConditionProviderService" msgid="1680513931165058425">"Дозвољава власнику да се повеже са интерфејсом највишег нивоа услуге добављача услова. Не би требало никада да буде потребно за уобичајене апликације."</string>
+ <string name="permlab_bindMediaRouteService" msgid="6637740382272686835">"повезивање са услугом усмеравања медија"</string>
+ <string name="permdesc_bindMediaRouteService" msgid="6436655024972496687">"Дозвољава власнику да се повеже са интерфејсом највишег нивоа услуге усмеравања медија. Никада не би требало да буде потребно за уобичајене апликације."</string>
<string name="permlab_bindDreamService" msgid="4153646965978563462">"повезивање са услугом сањарења"</string>
<string name="permdesc_bindDreamService" msgid="7325825272223347863">"Дозвољава власнику да се повеже са интерфејсом услуге сањарења највишег нивоа. Уобичајене апликације никада не би требало да је користе."</string>
<string name="permlab_invokeCarrierSetup" msgid="3699600833975117478">"позивање апликације са конфигурацијом коју одређује оператер"</string>
@@ -1283,6 +1285,9 @@
<skip />
<string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"Није могуће повезати са Wi-Fi мрежом"</string>
<string name="wifi_watchdog_network_disabled_detailed" msgid="5548780776418332675">" има лошу интернет везу."</string>
+ <string name="wifi_connect_alert_title" msgid="8455846016001810172">"Желите ли да дозволите повезивање?"</string>
+ <string name="wifi_connect_alert_message" msgid="8930084523889618078">"%1$s жели да се повеже са мрежом %2$s"</string>
+ <string name="wifi_connect_default_application" msgid="7143109390475484319">"Апликација"</string>
<string name="wifi_p2p_dialog_title" msgid="97611782659324517">"Wi-Fi Direct"</string>
<string name="wifi_p2p_turnon_message" msgid="2909250942299627244">"Покрените Wi-Fi Direct. Тиме ћете искључити клијента/хотспот за Wi-Fi."</string>
<string name="wifi_p2p_failed_message" msgid="3763669677935623084">"Није могуће покренути Wi-Fi Direct."</string>
@@ -1776,8 +1781,7 @@
<string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Тражи лозинку пре откачињања"</string>
<string name="battery_saver_description" msgid="2510530476513605742">"Да би смањила потрошњу батерије, Штедња батерије снижава перформансе уређаја, ограничава вибрацију и већину позадинских података. Имејл, размена порука и друге апликације које се ослањају на синхронизацију се можда неће ажурирати ако их не отворите.\n\nШтедња батерије се аутоматски искључује када се уређај пуни."</string>
<string name="downtime_condition_summary" msgid="8761776337475705749">"Док се прекид рада не заврши у <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
- <!-- no translation found for downtime_condition_line_one (8762708714645352010) -->
- <skip />
+ <string name="downtime_condition_line_one" msgid="8762708714645352010">"Док се време одмора не заврши"</string>
<plurals name="zen_mode_duration_minutes_summary">
<item quantity="one" msgid="3177683545388923234">"Један минут (до <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
<item quantity="other" msgid="2787867221129368935">"%1$d минута (до <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
@@ -1797,8 +1801,6 @@
<string name="zen_mode_until" msgid="7336308492289875088">"До <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
<string name="zen_mode_forever" msgid="4316804956488785559">"Бесконачно"</string>
<string name="toolbar_collapse_description" msgid="2821479483960330739">"Скупи"</string>
- <!-- no translation found for zen_mode_next_alarm_summary (5915140424683747372) -->
- <skip />
- <!-- no translation found for zen_mode_next_alarm_line_one (5537042951553420916) -->
- <skip />
+ <string name="zen_mode_next_alarm_summary" msgid="5915140424683747372">"До следећег аларма у <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
+ <string name="zen_mode_next_alarm_line_one" msgid="5537042951553420916">"До следећег аларма"</string>
</resources>
diff --git a/core/res/res/values-sv/strings.xml b/core/res/res/values-sv/strings.xml
index f8338df..e6a5252 100644
--- a/core/res/res/values-sv/strings.xml
+++ b/core/res/res/values-sv/strings.xml
@@ -41,8 +41,6 @@
<string name="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g> sekunder"</string>
<string name="durationSecond" msgid="985669622276420331">"<xliff:g id="SECONDS">%1$d</xliff:g> sekund"</string>
<string name="untitled" msgid="4638956954852782576">"<Okänd>"</string>
- <string name="ellipsis" msgid="7899829516048813237">"…"</string>
- <string name="ellipsis_two_dots" msgid="1228078994866030736">".."</string>
<string name="emptyPhoneNumber" msgid="7694063042079676517">"(Inget telefonnummer)"</string>
<string name="unknownName" msgid="2277556546742746522">"(Okänd)"</string>
<string name="defaultVoiceMailAlphaTag" msgid="2660020990097733077">"Röstbrevlåda"</string>
@@ -415,6 +413,8 @@
<string name="permdesc_bindRemoteDisplay" msgid="1261242718727295981">"Innehavaren tillåts att binda till den översta nivåns gränssnitt för en fjärrskärm. Ska inte behövas för vanliga appar."</string>
<string name="permlab_bindRemoteViews" msgid="5697987759897367099">"bind till en widget"</string>
<string name="permdesc_bindRemoteViews" msgid="4717987810137692572">"Innehavaren tillåts att binda till den översta nivåns gränssnitt för en widget. Ska inte behövas för vanliga appar."</string>
+ <string name="permlab_bindRouteProvider" msgid="4869394607915096847">"bind till en ruttleverantörstjänst"</string>
+ <string name="permdesc_bindRouteProvider" msgid="4703804520859960329">"Tillåter att innehavaren binds till en registrerad ruttleverantör. Detta ska inte behövas för vanliga appar."</string>
<string name="permlab_bindDeviceAdmin" msgid="8704986163711455010">"arbeta med en enhetsadministratör"</string>
<string name="permdesc_bindDeviceAdmin" msgid="569715419543907930">"Tillåter att innehavaren skickar avsikter till en enhetsadministratör. Vanliga appar behöver aldrig göra detta."</string>
<string name="permlab_bindTvInput" msgid="5601264742478168987">"binda till en tv-insignal"</string>
@@ -742,6 +742,8 @@
<string name="permdesc_bindNotificationListenerService" msgid="985697918576902986">"Innehavaren tillåts att binda till den översta nivåns gränssnitt för en meddelandelyssnare. Ska inte behövas för vanliga appar."</string>
<string name="permlab_bindConditionProviderService" msgid="1180107672332704641">"bind till en leverantörstjänst"</string>
<string name="permdesc_bindConditionProviderService" msgid="1680513931165058425">"Innehavaren tillåts att binda till den översta nivåns gränssnitt för en leverantörstjänst. Ska inte behövas för vanliga appar."</string>
+ <string name="permlab_bindMediaRouteService" msgid="6637740382272686835">"binda till medieruttjänst"</string>
+ <string name="permdesc_bindMediaRouteService" msgid="6436655024972496687">"Tillåter att innehavaren kan binda till den översta nivåns gränssnitt för en medieruttjänst. Detta ska inte behövas för vanliga appar."</string>
<string name="permlab_bindDreamService" msgid="4153646965978563462">"binda till en drömtjänst"</string>
<string name="permdesc_bindDreamService" msgid="7325825272223347863">"Innehavaren tillåts att binda till den översta nivåns gränssnitt för en drömtjänst. Ska inte behövas för vanliga appar."</string>
<string name="permlab_invokeCarrierSetup" msgid="3699600833975117478">"anropa konfigurationsappen från operatören"</string>
@@ -1283,6 +1285,9 @@
<skip />
<string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"Det gick inte att ansluta till Wi-Fi"</string>
<string name="wifi_watchdog_network_disabled_detailed" msgid="5548780776418332675">" har en dålig Internetanslutning."</string>
+ <string name="wifi_connect_alert_title" msgid="8455846016001810172">"Tillåt anslutning?"</string>
+ <string name="wifi_connect_alert_message" msgid="8930084523889618078">"%1$s vill ansluta till %2$s"</string>
+ <string name="wifi_connect_default_application" msgid="7143109390475484319">"En app"</string>
<string name="wifi_p2p_dialog_title" msgid="97611782659324517">"Wi-Fi direkt"</string>
<string name="wifi_p2p_turnon_message" msgid="2909250942299627244">"Starta direkt Wi-Fi-användning. Detta inaktiverar Wi-Fi-användning med klient/trådlös surfzon."</string>
<string name="wifi_p2p_failed_message" msgid="3763669677935623084">"Det gick inte att starta Wi-Fi direkt."</string>
@@ -1776,8 +1781,7 @@
<string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Be om lösenord innan skärmen slutar fästas"</string>
<string name="battery_saver_description" msgid="2510530476513605742">"I batterisparläget reduceras enhetens prestanda så att batteriet ska räcka längre, och vibration samt den mesta användningen av bakgrundsdata begränsas. Det kan hända att appar för e-post, chatt och annat som kräver synkronisering inte uppdateras förrän du öppnar dem.\n\nBatterisparläget inaktiveras automatiskt när enheten laddas."</string>
<string name="downtime_condition_summary" msgid="8761776337475705749">"Tills avbrottstiden är slut <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
- <!-- no translation found for downtime_condition_line_one (8762708714645352010) -->
- <skip />
+ <string name="downtime_condition_line_one" msgid="8762708714645352010">"Tills avbrottstiden är slut"</string>
<plurals name="zen_mode_duration_minutes_summary">
<item quantity="one" msgid="3177683545388923234">"I en minut (till kl. <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
<item quantity="other" msgid="2787867221129368935">"I %1$d minuter (till kl. <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
@@ -1797,8 +1801,6 @@
<string name="zen_mode_until" msgid="7336308492289875088">"Till kl. <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
<string name="zen_mode_forever" msgid="4316804956488785559">"För alltid"</string>
<string name="toolbar_collapse_description" msgid="2821479483960330739">"Komprimera"</string>
- <!-- no translation found for zen_mode_next_alarm_summary (5915140424683747372) -->
- <skip />
- <!-- no translation found for zen_mode_next_alarm_line_one (5537042951553420916) -->
- <skip />
+ <string name="zen_mode_next_alarm_summary" msgid="5915140424683747372">"Till nästa alarm kl. <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
+ <string name="zen_mode_next_alarm_line_one" msgid="5537042951553420916">"Till nästa alarm"</string>
</resources>
diff --git a/core/res/res/values-sw/strings.xml b/core/res/res/values-sw/strings.xml
index a12707c..6f49ddd 100644
--- a/core/res/res/values-sw/strings.xml
+++ b/core/res/res/values-sw/strings.xml
@@ -41,8 +41,6 @@
<string name="durationSeconds" msgid="8050088505238241405">"Sekunde <xliff:g id="SECONDS">%1$d</xliff:g>"</string>
<string name="durationSecond" msgid="985669622276420331">"Sekunde <xliff:g id="SECONDS">%1$d</xliff:g>"</string>
<string name="untitled" msgid="4638956954852782576">"<Haina jina>"</string>
- <string name="ellipsis" msgid="7899829516048813237">"…"</string>
- <string name="ellipsis_two_dots" msgid="1228078994866030736">"‥"</string>
<string name="emptyPhoneNumber" msgid="7694063042079676517">"(Hakuna nambari ya simu)"</string>
<string name="unknownName" msgid="2277556546742746522">"(Haijulikani)"</string>
<string name="defaultVoiceMailAlphaTag" msgid="2660020990097733077">"Barua ya sauti"</string>
@@ -415,6 +413,8 @@
<string name="permdesc_bindRemoteDisplay" msgid="1261242718727295981">"Huruhusu mtumiaji kujifungia kiolesura cha kiwango cha juu cha mwonekano wa mbali. Haipaswi kuhitajika kwa programu za kawaida."</string>
<string name="permlab_bindRemoteViews" msgid="5697987759897367099">"funga kwenye huduma ya widget"</string>
<string name="permdesc_bindRemoteViews" msgid="4717987810137692572">"Inaruhusu mmiliki kushurutisha kusano ya kiwango cha juu ya huduma ya wijeti. Haipaswi kuhitajika kwa programu za kawaida."</string>
+ <string name="permlab_bindRouteProvider" msgid="4869394607915096847">"bandika kwenye huduma ya mtoa huduma za njia"</string>
+ <string name="permdesc_bindRouteProvider" msgid="4703804520859960329">"Huruhusu mmiliki kubandika kwenye watoa huduma za njia waliosajiliwa. Haipaswi kuhitajika kwa programu za kawaida."</string>
<string name="permlab_bindDeviceAdmin" msgid="8704986163711455010">"jiunge na msimamizi wa kifaa"</string>
<string name="permdesc_bindDeviceAdmin" msgid="569715419543907930">"Humruhusu mmiliki kutuma kidhibiti cha kifaa malengo. Programu za kawaida hazikihitaji."</string>
<string name="permlab_bindTvInput" msgid="5601264742478168987">"bandika kwenye zana za data ya runinga"</string>
@@ -491,7 +491,7 @@
<string name="permlab_writeCallLog" msgid="8552045664743499354">"kuandika rekodi ya simu"</string>
<string name="permdesc_writeCallLog" product="tablet" msgid="6661806062274119245">"Huruhusu programu kurekebisha rajisi ya kompyuta kibao yako, ikiwa ni pamoja na simu zinazoingia na kutoka. Huenda programu hasidi zikatumia hii ili kufuta au kurekebisha rajisi ya simu yako."</string>
<string name="permdesc_writeCallLog" product="default" msgid="683941736352787842">"Huruhusu programu kurekebisha rajisi ya simu yako, ikiwa ni pamoja na simu zinazoingia na kutoka. Huenda programu hasidi zikatumia hii ili kufuta au kurekebisha rajisi ya simu yako."</string>
- <string name="permlab_readProfile" msgid="4701889852612716678">"soma kadi yako mwenyewe ya mawasiliano"</string>
+ <string name="permlab_readProfile" msgid="4701889852612716678">"kusoma kadi yako ya mawasiliano"</string>
<string name="permdesc_readProfile" product="default" msgid="5462475151849888848">"Inaruhusu programu kusoma taarifa ya kibinafsi ya maelezo mafupi yaliyohifadhiwa kwenye kifaa chako, kama vile jina lako na taarifa ya anwani. Hii inamaanisha kuwa programu inaweza kukutambua na inaweza kuwatumia wengine taarifa yako ya maelezo mafupi."</string>
<string name="permlab_writeProfile" msgid="907793628777397643">"rekebisha kadi yako mwenyewe ya mawasiliano"</string>
<string name="permdesc_writeProfile" product="default" msgid="5552084294598465899">"Inaruhusu programu kubadilisha au kuongeza taarifa ya maelezo mafupi ya kibinafsi yaliyohifadhiwa kwenye kifaa chako, kama vile jina lako na taarifa ya anwani. Hii inamaanisha kuwa programu inaweza kukutambua na inaweza kutuma taarifa ya maelezo yako mafupi kwa wengine."</string>
@@ -513,7 +513,7 @@
<string name="permdesc_accessLocationExtraCommands" msgid="6078307221056649927">"Ruhusu programu kufikia amri za ziada za mtoa huduma za mahali. Hii huenda ikaruhusu programu ikatize matumizi ya GPS au vyanzo vingine vya eneo."</string>
<string name="permlab_installLocationProvider" msgid="6578101199825193873">"kibali ili kusakinisha mtoa huduma ya mahali"</string>
<string name="permdesc_installLocationProvider" msgid="9066146120470591509">"Unda vyanzo vya eneo la majaribio vya kujaribu au kusakinisha mtoaji huduma mpya wa eneo. Hii inaruhusu programu kufuta eneo na/au hali zilizorudishwa na vyanzo vingine vya eneo kama vile GPS au watoaji huduma wa eneo."</string>
- <string name="permlab_accessFineLocation" msgid="1191898061965273372">"eneo sahihi (GPS na mtandao)"</string>
+ <string name="permlab_accessFineLocation" msgid="1191898061965273372">"kutambua eneo sahihi (GPS na mtandao)"</string>
<string name="permdesc_accessFineLocation" msgid="5295047563564981250">"Inaruhusu programu kupata eneo lako sahihi kwa kutumia Mfumo wa Mkao Ulimwenguni (GPS) au vyanzo vya mtandao vya eneo kama vile minara na Wi-Fi. Lazima huduma hizi za eneo ziwashwe na kupatikana kwenye kifaa chako ili programu izitumie. Huenda programu zikatumia hii kutambua ulipo, na zinaweza kutumia kawi ya ziada ya betri."</string>
<string name="permlab_accessCoarseLocation" msgid="4887895362354239628">"kukadiria eneo (kwenye mtandao)"</string>
<string name="permdesc_accessCoarseLocation" msgid="2538200184373302295">"Inaruhusu programu kupata eneo lako la kukadiria. Eneo hili linatokana na huduma za maeneo kwa kutumia vyanzo vya mtandao vya eneo kama vile minara na Wi-Fi. Lazima huduma hizi za eneo ziwashwe na kupatikana kwenye kifaa chako ili programu izitumie. Huenda programu zikatumia hii kutambua ulipo kwa kukadiria."</string>
@@ -742,6 +742,8 @@
<string name="permdesc_bindNotificationListenerService" msgid="985697918576902986">"Inaruhusu kishikilizi kuunganishwa kwenye kusano cha kiwango cha juu cha huduma ya kisikilizi cha arifa. Haipaswi kuhitajika tena kwa programu za kawaida."</string>
<string name="permlab_bindConditionProviderService" msgid="1180107672332704641">"bandika kwenye huduma ya mtoa masharti"</string>
<string name="permdesc_bindConditionProviderService" msgid="1680513931165058425">"Humruhusu mmiliki kubandika kwenye kiolesura cha kiwango cha juu cha huduma ya mtoa masharti. Isihitajike kamwe kwa pogramu za kawaida."</string>
+ <string name="permlab_bindMediaRouteService" msgid="6637740382272686835">"bandika kwenye huduma ya njia za sauti, picha na video."</string>
+ <string name="permdesc_bindMediaRouteService" msgid="6436655024972496687">"Humruhusu mmiliki kubandika kwenye kiolesura cha ngazi ya juu cha huduma ya njia za sauti, picha na video. Haipaswi kuhitajika kwa programu za kawaida."</string>
<string name="permlab_bindDreamService" msgid="4153646965978563462">"shurutisha kwa huduma murua"</string>
<string name="permdesc_bindDreamService" msgid="7325825272223347863">"Huruhusu mmiliki kushurutisha kwenye kiolesura cha kiwango cha juu cha huduma murua. Haipaswi kuhitajika kwa programu za kawaida."</string>
<string name="permlab_invokeCarrierSetup" msgid="3699600833975117478">"omba programu ya usakinishaji inayotolewa na mtoa huduma."</string>
@@ -1283,6 +1285,9 @@
<skip />
<string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"Haikuweza kuunganisha kwa Mtandao-Hewa"</string>
<string name="wifi_watchdog_network_disabled_detailed" msgid="5548780776418332675">" ina muunganisho duni wa Mtandao."</string>
+ <string name="wifi_connect_alert_title" msgid="8455846016001810172">"Ungepenga kuruhusu muunganisho?"</string>
+ <string name="wifi_connect_alert_message" msgid="8930084523889618078">"%1$s angependa kuunganisha kwenye %2$s"</string>
+ <string name="wifi_connect_default_application" msgid="7143109390475484319">"Programu"</string>
<string name="wifi_p2p_dialog_title" msgid="97611782659324517">"Mtandao hewa Moja kwa moja"</string>
<string name="wifi_p2p_turnon_message" msgid="2909250942299627244">"Anzisha Wi-Fi Moja kwa Moja. Hii itazima mteja/mtandao-hewa wa Wi-Fi."</string>
<string name="wifi_p2p_failed_message" msgid="3763669677935623084">"Haikuweza kuanzisha Wi-Fi Moja kwa Moja."</string>
diff --git a/core/res/res/values-ta-rIN/strings.xml b/core/res/res/values-ta-rIN/strings.xml
index 5e55f1b..6ee3f2c 100644
--- a/core/res/res/values-ta-rIN/strings.xml
+++ b/core/res/res/values-ta-rIN/strings.xml
@@ -41,8 +41,6 @@
<string name="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g> வினாடிகள்"</string>
<string name="durationSecond" msgid="985669622276420331">"<xliff:g id="SECONDS">%1$d</xliff:g> வினாடி"</string>
<string name="untitled" msgid="4638956954852782576">"<பெயரிடப்படாதது>"</string>
- <string name="ellipsis" msgid="7899829516048813237">"…"</string>
- <string name="ellipsis_two_dots" msgid="1228078994866030736">"‥"</string>
<string name="emptyPhoneNumber" msgid="7694063042079676517">"(தொலைபேசி எண் இல்லை)"</string>
<string name="unknownName" msgid="2277556546742746522">"(அறியப்படாதது)"</string>
<string name="defaultVoiceMailAlphaTag" msgid="2660020990097733077">"குரலஞ்சல்"</string>
@@ -415,6 +413,8 @@
<string name="permdesc_bindRemoteDisplay" msgid="1261242718727295981">"தொலைநிலைக் காட்சியின் உயர் நிலை இடைமுகத்துடன் இணைப்பதற்கு ஹோல்டரை அனுமதிக்கிறது. இயல்பான பயன்பாடுகளுக்கு எப்போதுமே தேவைப்படாது."</string>
<string name="permlab_bindRemoteViews" msgid="5697987759897367099">"விட்ஜெட் சேவையுடன் இணைத்தல்"</string>
<string name="permdesc_bindRemoteViews" msgid="4717987810137692572">"விட்ஜெட் சேவையின் உயர் நிலை இடைமுகத்துடன் இணைப்பதற்கு ஹோல்டரை அனுமதிக்கிறது. சாதாரண பயன்பாடுகளுக்கு எப்போதுமே தேவைப்படாது."</string>
+ <string name="permlab_bindRouteProvider" msgid="4869394607915096847">"வழு வழங்குநர் சேவையுடன் இணைத்தல்"</string>
+ <string name="permdesc_bindRouteProvider" msgid="4703804520859960329">"பதிவு செய்த எந்தவொரு வழி வழங்குநர்கள் சேவையின் உயர் நிலை இடைமுகத்துடன் இணைப்பதற்கு ஹோல்டரை அனுமதிக்கிறது. சாதாரண பயன்பாடுகளுக்கு எப்போதுமே தேவைப்படாது."</string>
<string name="permlab_bindDeviceAdmin" msgid="8704986163711455010">"சாதன நிர்வாகியுடன் ஊடாடுதல்"</string>
<string name="permdesc_bindDeviceAdmin" msgid="569715419543907930">"சாதன நிர்வாகிக்கு இன்டென்ட்ஸை அனுப்ப, ஹோல்டரை அனுமதிக்கிறது. சாதாரண பயன்பாடுகளுக்கு எப்போதுமே தேவைப்படாது."</string>
<string name="permlab_bindTvInput" msgid="5601264742478168987">"டிவி உள்ளீட்டுடன் இணைத்தல்"</string>
@@ -742,6 +742,8 @@
<string name="permdesc_bindNotificationListenerService" msgid="985697918576902986">"அறிவிப்புகளைக் கண்காணிக்கும் சேவையின் உயர் நிலை இடைமுகத்துடன் இணைப்பதற்கு ஹோல்டரை அனுமதிக்கிறது. இயல்பான பயன்பாடுகளுக்கு எப்போதுமே தேவைப்படாது."</string>
<string name="permlab_bindConditionProviderService" msgid="1180107672332704641">"நிபந்தனை வழங்குநர் சேவையுடன் இணைத்தல்"</string>
<string name="permdesc_bindConditionProviderService" msgid="1680513931165058425">"நிபந்தனை வழங்குநர் சேவையின் உயர் நிலை இடைமுகத்துடன் இணைப்பதற்கு ஹோல்டரை அனுமதிக்கிறது. சாதாரண பயன்பாடுகளுக்கு எப்போதுமே தேவைப்படாது."</string>
+ <string name="permlab_bindMediaRouteService" msgid="6637740382272686835">"மீடியா வழிச் சேவையுடன் இணைத்தல்"</string>
+ <string name="permdesc_bindMediaRouteService" msgid="6436655024972496687">"மீடியா வழிச் சேவையின் உயர்-அளவு இடைமுகத்துடன் இணைக்க உரிமையாளரை அனுமதிக்கிறது. சாதாரண பயன்பாடுகளுக்கு ஒருபோதும் தேவையில்லை."</string>
<string name="permlab_bindDreamService" msgid="4153646965978563462">"டிரீம் சேவையுடன் இணை"</string>
<string name="permdesc_bindDreamService" msgid="7325825272223347863">"டிரீம் சேவையின் உயர் நிலை இடைமுகத்துடன் இணைப்பதற்கு ஹோல்டரை அனுமதிக்கிறது. இயல்பான பயன்பாடுகளுக்கு எப்போதுமே தேவைப்படாது."</string>
<string name="permlab_invokeCarrierSetup" msgid="3699600833975117478">"மொபைல் நிறுவனம் வழங்கிய உள்ளமைவு பயன்பாட்டை செயலாக்குதல்"</string>
@@ -1283,6 +1285,9 @@
<skip />
<string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"வைஃபை உடன் இணைக்க முடியவில்லை"</string>
<string name="wifi_watchdog_network_disabled_detailed" msgid="5548780776418332675">" இணைய இணைப்பு மோசமாக உள்ளது."</string>
+ <string name="wifi_connect_alert_title" msgid="8455846016001810172">"இணைப்பை அனுமதிக்கவா?"</string>
+ <string name="wifi_connect_alert_message" msgid="8930084523889618078">"%1$s , %2$s உடன் இணைக்க விரும்புகிறது"</string>
+ <string name="wifi_connect_default_application" msgid="7143109390475484319">"ஒரு பயன்பாடு"</string>
<string name="wifi_p2p_dialog_title" msgid="97611782659324517">"வைஃபை Direct"</string>
<string name="wifi_p2p_turnon_message" msgid="2909250942299627244">"வைஃபை Direct ஐத் தொடங்குக. இது வைஃபை க்ளையண்ட்/ஹாட்ஸ்பாட்டை முடக்கும்."</string>
<string name="wifi_p2p_failed_message" msgid="3763669677935623084">"வைஃபை Direct ஐத் தொடங்க முடியவில்லை."</string>
@@ -1776,8 +1781,7 @@
<string name="lock_to_app_unlock_password" msgid="6380979775916974414">"அகற்றும் முன் கடவுச்சொல்லைக் கேள்"</string>
<string name="battery_saver_description" msgid="2510530476513605742">"பேட்டரியின் ஆயுட்காலத்தை அதிகரிக்க, பேட்டரி சேமிப்பான் சாதனத்தின் செயல்திறனைக் குறைத்து, அதிர்வுறுவதையும் பெரும்பாலான பின்புலத் தரவையும் வரம்பிடுகிறது. ஒத்திசைவைச் சார்ந்திருக்கும் மின்னஞ்சல், மெசேஜ், மேலும் பிற பயன்பாடுகளைத் திறக்கும் வரை, அவை புதுப்பிக்கப்படாமல் இருக்கலாம்.\n\nசாதனம் சார்ஜ் ஆகும் போது, பேட்டரி சேமிப்பான் தானாகவே முடக்கப்படும்."</string>
<string name="downtime_condition_summary" msgid="8761776337475705749">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g> முடியும் வரை"</string>
- <!-- no translation found for downtime_condition_line_one (8762708714645352010) -->
- <skip />
+ <string name="downtime_condition_line_one" msgid="8762708714645352010">"செயலற்ற நேரம் முடியும் வரை"</string>
<plurals name="zen_mode_duration_minutes_summary">
<item quantity="one" msgid="3177683545388923234">"ஒரு நிமிடத்திற்கு (<xliff:g id="FORMATTEDTIME">%2$s</xliff:g> வரை)"</item>
<item quantity="other" msgid="2787867221129368935">"%1$d நிமிடங்களுக்கு (<xliff:g id="FORMATTEDTIME">%2$s</xliff:g> வரை)"</item>
@@ -1797,8 +1801,6 @@
<string name="zen_mode_until" msgid="7336308492289875088">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g> வரை"</string>
<string name="zen_mode_forever" msgid="4316804956488785559">"வரையறையற்றது"</string>
<string name="toolbar_collapse_description" msgid="2821479483960330739">"சுருக்கு"</string>
- <!-- no translation found for zen_mode_next_alarm_summary (5915140424683747372) -->
- <skip />
- <!-- no translation found for zen_mode_next_alarm_line_one (5537042951553420916) -->
- <skip />
+ <string name="zen_mode_next_alarm_summary" msgid="5915140424683747372">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g>க்கு ஒலிக்கும் அடுத்த அலாரம் வரை"</string>
+ <string name="zen_mode_next_alarm_line_one" msgid="5537042951553420916">"அடுத்த அலாரம் வரை"</string>
</resources>
diff --git a/core/res/res/values-te-rIN/strings.xml b/core/res/res/values-te-rIN/strings.xml
index de434ca..64f9f0e 100644
--- a/core/res/res/values-te-rIN/strings.xml
+++ b/core/res/res/values-te-rIN/strings.xml
@@ -41,8 +41,6 @@
<string name="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g> సెకన్లు"</string>
<string name="durationSecond" msgid="985669622276420331">"<xliff:g id="SECONDS">%1$d</xliff:g> సెకను"</string>
<string name="untitled" msgid="4638956954852782576">"<శీర్షిక లేనిది>"</string>
- <string name="ellipsis" msgid="7899829516048813237">"…"</string>
- <string name="ellipsis_two_dots" msgid="1228078994866030736">"‥"</string>
<string name="emptyPhoneNumber" msgid="7694063042079676517">"(ఫోన్ నంబర్ లేదు)"</string>
<string name="unknownName" msgid="2277556546742746522">"(తెలియదు)"</string>
<string name="defaultVoiceMailAlphaTag" msgid="2660020990097733077">"వాయిస్ మెయిల్"</string>
@@ -415,6 +413,8 @@
<string name="permdesc_bindRemoteDisplay" msgid="1261242718727295981">"రిమోట్ డిస్ప్లే యొక్క అగ్ర-స్థాయి ఇంటర్ఫేస్కు అనుబంధించడానికి హోల్డర్ను అనుమతిస్తుంది. సాధారణ అనువర్తనాల కోసం ఎప్పటికీ అవసరం ఉండకూడదు."</string>
<string name="permlab_bindRemoteViews" msgid="5697987759897367099">"విడ్జెట్ సేవకు అనుబంధించడం"</string>
<string name="permdesc_bindRemoteViews" msgid="4717987810137692572">"విడ్జెట్ సేవ యొక్క అగ్ర-స్థాయి ఇంటర్ఫేస్కు అనుబంధించడానికి హోల్డర్ను అనుమతిస్తుంది. సాధారణ అనువర్తనాలకు ఎప్పటికీ అవసరం ఉండదు."</string>
+ <string name="permlab_bindRouteProvider" msgid="4869394607915096847">"మార్గ ప్రదాత సేవకు అనుబంధించడం"</string>
+ <string name="permdesc_bindRouteProvider" msgid="4703804520859960329">"నమోదిత మార్గ ప్రదాతల్లో వేటికైనా అనుబంధించడానికి హోల్డర్ను అనుమతిస్తుంది. సాధారణ అనువర్తనాలకు ఎప్పటికీ అవసరం ఉండదు."</string>
<string name="permlab_bindDeviceAdmin" msgid="8704986163711455010">"పరికర నిర్వాహికితో పరస్పర చర్య చేయడం"</string>
<string name="permdesc_bindDeviceAdmin" msgid="569715419543907930">"పరికర నిర్వాహకుడికి లక్ష్యాలను పంపడానికి హోల్డర్ను అనుమతిస్తుంది. సాధారణ అనువర్తనాలకు ఎప్పటికీ అవసరం ఉండదు."</string>
<string name="permlab_bindTvInput" msgid="5601264742478168987">"టీవీ ఇన్పుట్కి అనుబంధించడం"</string>
@@ -742,6 +742,8 @@
<string name="permdesc_bindNotificationListenerService" msgid="985697918576902986">"నోటిఫికేషన్ పరిశీలన సేవ యొక్క అగ్ర-స్థాయి ఇంటర్ఫేస్కు అనుబంధించడానికి హోల్డర్ను అనుమతిస్తుంది. సాధారణ అనువర్తనాల కోసం ఎప్పటికీ అవసరం ఉండకూడదు."</string>
<string name="permlab_bindConditionProviderService" msgid="1180107672332704641">"షరతు ప్రదాత సేవకు అనుబంధించడం"</string>
<string name="permdesc_bindConditionProviderService" msgid="1680513931165058425">"షరతు ప్రదాత సేవ యొక్క అగ్ర-స్థాయి ఇంటర్ఫేస్కు అనుబంధించడానికి హోల్డర్ను అనుమతిస్తుంది. సాధారణ అనువర్తనాలకు ఎప్పటికీ అవసరం ఉండదు."</string>
+ <string name="permlab_bindMediaRouteService" msgid="6637740382272686835">"మీడియా మార్గ సేవకు అనుబంధించడం"</string>
+ <string name="permdesc_bindMediaRouteService" msgid="6436655024972496687">"మీడియా మార్గ సేవ యొక్క అగ్ర-స్థాయి ఇంటర్ఫేస్కు అనుబంధించడానికి హోల్డర్ను అనుమతిస్తుంది. సాధారణ అనువర్తనాలకు ఎప్పటికీ అవసరం ఉండదు."</string>
<string name="permlab_bindDreamService" msgid="4153646965978563462">"డ్రీమ్ సేవకి అనుబంధించడం"</string>
<string name="permdesc_bindDreamService" msgid="7325825272223347863">"డ్రీమ్ సేవ యొక్క అగ్ర-స్థాయి ఇంటర్ఫేస్కు అనుబంధించడానికి హోల్డర్ను అనుమతిస్తుంది. సాధారణ అనువర్తనాలకు ఎప్పటికీ అవసరం ఉండదు."</string>
<string name="permlab_invokeCarrierSetup" msgid="3699600833975117478">"క్యారియర్ అందించిన కాన్ఫిగరేషన్ అనువర్తనాన్ని అభ్యర్థించడం"</string>
@@ -1283,6 +1285,9 @@
<skip />
<string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"Wi-Fiకి కనెక్ట్ చేయడం సాధ్యపడలేదు"</string>
<string name="wifi_watchdog_network_disabled_detailed" msgid="5548780776418332675">" బలహీన ఇంటర్నెట్ కనెక్షన్ను కలిగి ఉంది."</string>
+ <string name="wifi_connect_alert_title" msgid="8455846016001810172">"కనెక్షన్ని అనుమతించాలా?"</string>
+ <string name="wifi_connect_alert_message" msgid="8930084523889618078">"%1$s %2$sకి కనెక్ట్ చేయాలనుకుంటున్నారు"</string>
+ <string name="wifi_connect_default_application" msgid="7143109390475484319">"ఒక అనువర్తనం"</string>
<string name="wifi_p2p_dialog_title" msgid="97611782659324517">"Wi-Fi Direct"</string>
<string name="wifi_p2p_turnon_message" msgid="2909250942299627244">"Wi-Fi Directను ప్రారంభించండి. దీని వలన Wi-Fi క్లయింట్/హాట్స్పాట్ ఆపివేయబడుతుంది."</string>
<string name="wifi_p2p_failed_message" msgid="3763669677935623084">"Wi-Fi Directను ప్రారంభించడం సాధ్యపడలేదు."</string>
@@ -1776,8 +1781,7 @@
<string name="lock_to_app_unlock_password" msgid="6380979775916974414">"అన్పిన్ చేయడానికి ముందు పాస్వర్డ్ కోసం అడుగు"</string>
<string name="battery_saver_description" msgid="2510530476513605742">"బ్యాటరీ సామర్థ్యాన్ని మెరుగుపరచడంలో సహాయపడటానికి, బ్యాటరీ సేవర్ మీ పరికరం పనితీరుని తగ్గిస్తుంది మరియు వైబ్రేషన్ను మరియు అత్యధిక నేపథ్య డేటాను పరిమితపరుస్తుంది. అలాగే సమకాలీకరణపై ఆధారపడే ఇమెయిల్, సందేశ సేవ మరియు ఇతర అనువర్తనాలు మీరు వాటిని తెరిస్తే మినహా నవీకరించబడకపోవచ్చు.\n\nమీ పరికరం ఛార్జింగ్లో ఉన్నప్పుడు బ్యాటరీ సేవర్ స్వయంచాలకంగా ఆఫ్ చేయబడుతుంది."</string>
<string name="downtime_condition_summary" msgid="8761776337475705749">"మీ వృథా సమయం <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>కి ముగిసే వరకు"</string>
- <!-- no translation found for downtime_condition_line_one (8762708714645352010) -->
- <skip />
+ <string name="downtime_condition_line_one" msgid="8762708714645352010">"మీ వృథా సమయం ముగిసేవరకు"</string>
<plurals name="zen_mode_duration_minutes_summary">
<item quantity="one" msgid="3177683545388923234">"ఒక నిమిషం పాటు (<xliff:g id="FORMATTEDTIME">%2$s</xliff:g> వరకు)"</item>
<item quantity="other" msgid="2787867221129368935">"%1$d నిమిషాల పాటు (<xliff:g id="FORMATTEDTIME">%2$s</xliff:g> వరకు)"</item>
@@ -1797,8 +1801,6 @@
<string name="zen_mode_until" msgid="7336308492289875088">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g> వరకు"</string>
<string name="zen_mode_forever" msgid="4316804956488785559">"నిరవధికంగా"</string>
<string name="toolbar_collapse_description" msgid="2821479483960330739">"కుదించండి"</string>
- <!-- no translation found for zen_mode_next_alarm_summary (5915140424683747372) -->
- <skip />
- <!-- no translation found for zen_mode_next_alarm_line_one (5537042951553420916) -->
- <skip />
+ <string name="zen_mode_next_alarm_summary" msgid="5915140424683747372">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g>కి సెట్ చేసిన తదుపరి అలారం వరకు"</string>
+ <string name="zen_mode_next_alarm_line_one" msgid="5537042951553420916">"తదుపరి అలారం వరకు"</string>
</resources>
diff --git a/core/res/res/values-th/strings.xml b/core/res/res/values-th/strings.xml
index a4e2662..91c8a76 100644
--- a/core/res/res/values-th/strings.xml
+++ b/core/res/res/values-th/strings.xml
@@ -41,8 +41,6 @@
<string name="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g> วินาที"</string>
<string name="durationSecond" msgid="985669622276420331">"<xliff:g id="SECONDS">%1$d</xliff:g> วินาที"</string>
<string name="untitled" msgid="4638956954852782576">"<ไม่มีชื่อ>"</string>
- <string name="ellipsis" msgid="7899829516048813237">"…"</string>
- <string name="ellipsis_two_dots" msgid="1228078994866030736">"‥"</string>
<string name="emptyPhoneNumber" msgid="7694063042079676517">"(ไม่มีหมายเลขโทรศัพท์)"</string>
<string name="unknownName" msgid="2277556546742746522">"(ไม่ทราบ)"</string>
<string name="defaultVoiceMailAlphaTag" msgid="2660020990097733077">"ข้อความเสียง"</string>
@@ -415,6 +413,8 @@
<string name="permdesc_bindRemoteDisplay" msgid="1261242718727295981">"อนุญาตให้ผู้ใช้ผูกกับอินเทอร์เฟซระดับสูงสุดของจอแสดงผลระยะไกล ซึ่งแอปพลิเคชันทั่วไปไม่จำเป็นต้องใช้"</string>
<string name="permlab_bindRemoteViews" msgid="5697987759897367099">"เชื่อมโยงกับบริการวิดเจ็ต"</string>
<string name="permdesc_bindRemoteViews" msgid="4717987810137692572">"อนุญาตให้ผู้ใช้เชื่อมโยงกับส่วนติดต่อผู้ใช้ระดับสูงสุดของบริการวิดเจ็ต ไม่ควรต้องใช้สำหรับแอปพลิเคชันทั่วไป"</string>
+ <string name="permlab_bindRouteProvider" msgid="4869394607915096847">"เชื่อมโยงกับบริการของผู้ให้บริการเส้นทาง"</string>
+ <string name="permdesc_bindRouteProvider" msgid="4703804520859960329">"ช่วยให้เจ้าของสามารถเชื่อมโยงกับผู้ให้บริการเส้นทางที่ลงทะเบียนรายใดก็ได้ ไม่จำเป็นสำหรับแอปทั่วไป"</string>
<string name="permlab_bindDeviceAdmin" msgid="8704986163711455010">"ติดต่อกับผู้ดูแลอุปกรณ์"</string>
<string name="permdesc_bindDeviceAdmin" msgid="569715419543907930">"อนุญาตให้ผู้ใช้ส่งการติดต่อไปยังโปรแกรมควบคุมอุปกรณ์ ไม่ควรต้องใช้สำหรับแอปพลิเคชันทั่วไป"</string>
<string name="permlab_bindTvInput" msgid="5601264742478168987">"เชื่อมโยงกับอินพุตทีวี"</string>
@@ -742,6 +742,8 @@
<string name="permdesc_bindNotificationListenerService" msgid="985697918576902986">"อนุญาตให้เจ้าของเชื่อมโยงกับอินเตอร์เฟซระดับสูงสุดของบริการตัวฟังการแจ้งเตือน ซึ่งไม่มีความจำเป็นสำหรับแอปธรรมดา"</string>
<string name="permlab_bindConditionProviderService" msgid="1180107672332704641">"เชื่อมโยงกับบริการของผู้เสนอเงื่อนไข"</string>
<string name="permdesc_bindConditionProviderService" msgid="1680513931165058425">"อนุญาตให้ผู้ใช้อุปกรณ์เชื่อมโยงกับอินเทอร์เฟซระดับบนสุดของบริการของผู้เสนอเงื่อนไข ไม่จำเป็นสำหรับแอปทั่วไป"</string>
+ <string name="permlab_bindMediaRouteService" msgid="6637740382272686835">"เชื่อมโยงกับบริการเส้นทางสื่อ"</string>
+ <string name="permdesc_bindMediaRouteService" msgid="6436655024972496687">"อนุญาตให้แอปพลิเคชันเชื่อมโยงกับอินเทอร์เฟซระดับบนสุดของบริการเส้นทางสื่อ ไม่จำเป็นสำหรับแอปทั่วไป"</string>
<string name="permlab_bindDreamService" msgid="4153646965978563462">"เชื่อมโยงกับบริการที่ต้องการ"</string>
<string name="permdesc_bindDreamService" msgid="7325825272223347863">"อนุญาตให้แอปพลิเคชันเชื่อมโยงกับอินเทอร์เฟซระดับบนสุดของบริการที่ต้องการ ไม่จำเป็นสำหรับแอปทั่วไป"</string>
<string name="permlab_invokeCarrierSetup" msgid="3699600833975117478">"เรียกใช้แอปการกำหนดค่าของผู้ให้บริการ"</string>
@@ -1283,6 +1285,9 @@
<skip />
<string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"ไม่สามารถเชื่อมต่อ WiFi"</string>
<string name="wifi_watchdog_network_disabled_detailed" msgid="5548780776418332675">" มีสัญญาณอินเทอร์เน็ตไม่ดี"</string>
+ <string name="wifi_connect_alert_title" msgid="8455846016001810172">"อนุญาตการเชื่อมต่อใช่ไหม"</string>
+ <string name="wifi_connect_alert_message" msgid="8930084523889618078">"%1$s ต้องการเชื่อมต่อ %2$s"</string>
+ <string name="wifi_connect_default_application" msgid="7143109390475484319">"แอปพลิเคชัน"</string>
<string name="wifi_p2p_dialog_title" msgid="97611782659324517">"WiFi Direct"</string>
<string name="wifi_p2p_turnon_message" msgid="2909250942299627244">"เริ่มการทำงาน WiFi Direct ซึ่งจะเป็นการปิดการทำงาน WiFi ไคลเอ็นต์/ฮอตสปอต"</string>
<string name="wifi_p2p_failed_message" msgid="3763669677935623084">"ไม่สามารถเริ่ม WiFi Direct ได้"</string>
@@ -1776,8 +1781,7 @@
<string name="lock_to_app_unlock_password" msgid="6380979775916974414">"ขอรหัสผ่านก่อนเลิกตรึง"</string>
<string name="battery_saver_description" msgid="2510530476513605742">"เพื่อให้สามารถใช้แบตเตอรี่ได้ยาวนานขึ้น โหมดประหยัดแบตเตอรี่จะลดการทำงานและการสั่นของอุปกรณ์ รวมถึงการใช้ข้อมูลแบ็กกราวด์เกือบทั้งหมด อีเมล การรับส่งข้อความ และแอปอื่นๆ ที่ใช้การซิงค์อาจไม่อัปเดตจนกว่าคุณจะเปิดใช้\n\nโหมดประหยัดแบตเตอรี่จะปิดอัตโนมัติเมื่อมีการชาร์จอุปกรณ์"</string>
<string name="downtime_condition_summary" msgid="8761776337475705749">"จนกว่าจะสิ้นสุดช่วงเวลาที่เครื่องไม่ทำงานในเวลา <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
- <!-- no translation found for downtime_condition_line_one (8762708714645352010) -->
- <skip />
+ <string name="downtime_condition_line_one" msgid="8762708714645352010">"จนกว่าจะสิ้นสุดช่วงเวลาเครื่องไม่ทำงาน"</string>
<plurals name="zen_mode_duration_minutes_summary">
<item quantity="one" msgid="3177683545388923234">"1 นาที (จนถึงเวลา <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
<item quantity="other" msgid="2787867221129368935">"%1$d นาที (จนถึงเวลา <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
@@ -1797,8 +1801,6 @@
<string name="zen_mode_until" msgid="7336308492289875088">"จนถึงเวลา <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
<string name="zen_mode_forever" msgid="4316804956488785559">"ไม่มีกำหนด"</string>
<string name="toolbar_collapse_description" msgid="2821479483960330739">"ยุบ"</string>
- <!-- no translation found for zen_mode_next_alarm_summary (5915140424683747372) -->
- <skip />
- <!-- no translation found for zen_mode_next_alarm_line_one (5537042951553420916) -->
- <skip />
+ <string name="zen_mode_next_alarm_summary" msgid="5915140424683747372">"จนถึงการตั้งปลุกครั้งถัดไปในเวลา <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
+ <string name="zen_mode_next_alarm_line_one" msgid="5537042951553420916">"จนถึงการตั้งปลุกครั้งถัดไป"</string>
</resources>
diff --git a/core/res/res/values-tl/strings.xml b/core/res/res/values-tl/strings.xml
index 7bc0367..2398f27 100644
--- a/core/res/res/values-tl/strings.xml
+++ b/core/res/res/values-tl/strings.xml
@@ -41,8 +41,6 @@
<string name="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g> (na) seg"</string>
<string name="durationSecond" msgid="985669622276420331">"<xliff:g id="SECONDS">%1$d</xliff:g> (na) seg"</string>
<string name="untitled" msgid="4638956954852782576">"<Walang pamagat>"</string>
- <string name="ellipsis" msgid="7899829516048813237">"…"</string>
- <string name="ellipsis_two_dots" msgid="1228078994866030736">"‥"</string>
<string name="emptyPhoneNumber" msgid="7694063042079676517">"(Walang numero ng telepono)"</string>
<string name="unknownName" msgid="2277556546742746522">"(Hindi kilala)"</string>
<string name="defaultVoiceMailAlphaTag" msgid="2660020990097733077">"Voicemail"</string>
@@ -415,6 +413,8 @@
<string name="permdesc_bindRemoteDisplay" msgid="1261242718727295981">"Binibigyang-daan ang may-hawak na masaklaw ang pinakamataas na antas ng interface ng isang remote na display. Hindi dapat kailanman kailanganin ng normal na apps."</string>
<string name="permlab_bindRemoteViews" msgid="5697987759897367099">"itali sa serbisyo ng widget"</string>
<string name="permdesc_bindRemoteViews" msgid="4717987810137692572">"Pinapayagan ang may-hawak na sumailalim sa nangungunang interface ng serbisyo ng widget. Hindi kailanman dapat na kailanganin para sa normal na apps."</string>
+ <string name="permlab_bindRouteProvider" msgid="4869394607915096847">"mag-bind sa isang serbisyo ng route provider"</string>
+ <string name="permdesc_bindRouteProvider" msgid="4703804520859960329">"Nagbibigay-daan sa may-pahintulot na mag-bind sa anumang nakarehistrong route provider. Hindi dapat kailanganin kailanman ng mga normal na app."</string>
<string name="permlab_bindDeviceAdmin" msgid="8704986163711455010">"makipag-ugnay sa tagapangasiwa ng device"</string>
<string name="permdesc_bindDeviceAdmin" msgid="569715419543907930">"Pinapayagan ang mga may-ari na magpadala ng mga layunin sa administrator ng device. Hindi kailanman dapat na kailanganin para sa normal na apps."</string>
<string name="permlab_bindTvInput" msgid="5601264742478168987">"i-bind sa isang TV input"</string>
@@ -742,6 +742,8 @@
<string name="permdesc_bindNotificationListenerService" msgid="985697918576902986">"Nagbibigay-daan sa may-ari na mapailalim sa interface sa tuktok na antas ng isang serbisyo ng notification listener. Hindi dapat kailanganin para sa karaniwang apps kahit kailan."</string>
<string name="permlab_bindConditionProviderService" msgid="1180107672332704641">"i-bind sa isang serbisyo sa pagbibigay ng kundisyon"</string>
<string name="permdesc_bindConditionProviderService" msgid="1680513931165058425">"Nagbibigay-daan sa naghahawak na i-bind ang top-level na interface ng isang serbisyo sa pagbibigay ng kundisyon. Hindi kailanman dapat kailanganin ng mga normal na app."</string>
+ <string name="permlab_bindMediaRouteService" msgid="6637740382272686835">"mag-bind sa isang serbisyo ng media route"</string>
+ <string name="permdesc_bindMediaRouteService" msgid="6436655024972496687">"Nagbibigay-daan sa may-hawak na mag-bind sa top-level na interface ng isang serbisyo ng media route. Hindi kailanman dapat kailanganin ng mga normal na app."</string>
<string name="permlab_bindDreamService" msgid="4153646965978563462">"sumailalim sa isang serbisyo ng dream"</string>
<string name="permdesc_bindDreamService" msgid="7325825272223347863">"Pinapayagan ang may-ari na sumailalim sa interface ng serbisyo ng dream na nasa nangungunang antas. Hindi kailanman dapat na kailanganin para sa mga normal na app."</string>
<string name="permlab_invokeCarrierSetup" msgid="3699600833975117478">"paganahin ang app ng configuration na ibinigay ng carrier"</string>
@@ -1283,6 +1285,9 @@
<skip />
<string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"Hindi makakonekta sa Wi-Fi"</string>
<string name="wifi_watchdog_network_disabled_detailed" msgid="5548780776418332675">" ay mayroong mahinang koneksyon sa Internet."</string>
+ <string name="wifi_connect_alert_title" msgid="8455846016001810172">"Payagan ang kuneksyon?"</string>
+ <string name="wifi_connect_alert_message" msgid="8930084523889618078">"gustong kumonekta ni %1$s sa %2$s"</string>
+ <string name="wifi_connect_default_application" msgid="7143109390475484319">"Isang application"</string>
<string name="wifi_p2p_dialog_title" msgid="97611782659324517">"Wi-Fi Direct"</string>
<string name="wifi_p2p_turnon_message" msgid="2909250942299627244">"Simulan ang Wi-Fi Direct. I-o-off nito ang client/hotspot ng Wi-Fi."</string>
<string name="wifi_p2p_failed_message" msgid="3763669677935623084">"Hindi masimulan ang Wi-Fi Direct"</string>
diff --git a/core/res/res/values-tr/strings.xml b/core/res/res/values-tr/strings.xml
index 0a1ab7d..1237835 100644
--- a/core/res/res/values-tr/strings.xml
+++ b/core/res/res/values-tr/strings.xml
@@ -41,8 +41,6 @@
<string name="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g> sn."</string>
<string name="durationSecond" msgid="985669622276420331">"<xliff:g id="SECONDS">%1$d</xliff:g> sn."</string>
<string name="untitled" msgid="4638956954852782576">"<Adsız>"</string>
- <string name="ellipsis" msgid="7899829516048813237">"…"</string>
- <string name="ellipsis_two_dots" msgid="1228078994866030736">"‥"</string>
<string name="emptyPhoneNumber" msgid="7694063042079676517">"(Telefon numarası yok)"</string>
<string name="unknownName" msgid="2277556546742746522">"(Bilinmiyor)"</string>
<string name="defaultVoiceMailAlphaTag" msgid="2660020990097733077">"Sesli Mesaj"</string>
@@ -415,6 +413,8 @@
<string name="permdesc_bindRemoteDisplay" msgid="1261242718727295981">"İzin sahibine, bir uzak ekranın en üst düzey arayüzüne bağlanma izni verir. Normal uygulamalarda hiçbir zaman gerek duyulmaz."</string>
<string name="permlab_bindRemoteViews" msgid="5697987759897367099">"bir widget hizmetine bağla"</string>
<string name="permdesc_bindRemoteViews" msgid="4717987810137692572">"Cihazın sahibine bir widget hizmetinin en üst düzey arayüzüne bağlanma izni verir. Normal uygulamalarda hiçbir zaman gerek duyulmaz."</string>
+ <string name="permlab_bindRouteProvider" msgid="4869394607915096847">"rota sağlayıcı hizmetine bağlanma"</string>
+ <string name="permdesc_bindRouteProvider" msgid="4703804520859960329">"İzin verilen uygulamaya tüm kayıtlı rota sağlayıcılarına bağlanma izni verir. Normal uygulamalarda hiçbir zaman gerek duyulmaz."</string>
<string name="permlab_bindDeviceAdmin" msgid="8704986163711455010">"bir cihaz yöneticisi ile etkileşimde bulun"</string>
<string name="permdesc_bindDeviceAdmin" msgid="569715419543907930">"Cihazın sahibinin cihaz yöneticisine amaç göndermesine izin verir. Normal uygulamalarda hiçbir zaman gerek duyulmaz."</string>
<string name="permlab_bindTvInput" msgid="5601264742478168987">"TV girişine bağlanma"</string>
@@ -742,6 +742,8 @@
<string name="permdesc_bindNotificationListenerService" msgid="985697918576902986">"İzin sahibine bir bildirim dinleyici hizmetinin en üst düzey arayüzüne bağlanma izni verir. Normal uygulamalarda hiçbir zaman gerek duyulmaz."</string>
<string name="permlab_bindConditionProviderService" msgid="1180107672332704641">"bir durum sağlayıcı hizmetine bağlanma"</string>
<string name="permdesc_bindConditionProviderService" msgid="1680513931165058425">"İzin sahibinin, bir durum sağlayıcı hizmete ait üst düzey arayüze bağlanmasına izin verir. Normal uygulamalar için hiçbir zaman gerekli değildir."</string>
+ <string name="permlab_bindMediaRouteService" msgid="6637740382272686835">"bir medya yönlendirme hizmetine bağlan"</string>
+ <string name="permdesc_bindMediaRouteService" msgid="6436655024972496687">"İzin sahibinin, bir medya yönlendirme hizmetine ait üst düzey arayüze bağlanmasına izin verir. Normal uygulamalar için hiçbir zaman gerekli değildir."</string>
<string name="permlab_bindDreamService" msgid="4153646965978563462">"bir dream hizmetine bağla"</string>
<string name="permdesc_bindDreamService" msgid="7325825272223347863">"İzin sahibine bir dream hizmetinin üst seviye arayüzüne bağlanma olanağı sunar. Normal uygulamalarda hiçbir zaman ihtiyaç duyulmamalıdır."</string>
<string name="permlab_invokeCarrierSetup" msgid="3699600833975117478">"operatör tarafından sağlanan yapılandırma uygulamasını çalıştır"</string>
@@ -1283,6 +1285,9 @@
<skip />
<string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"Kablosuz bağlantısı kurulamadı"</string>
<string name="wifi_watchdog_network_disabled_detailed" msgid="5548780776418332675">" İnternet bağlantısı zayıf."</string>
+ <string name="wifi_connect_alert_title" msgid="8455846016001810172">"Bağlantıya izin verilsin mi?"</string>
+ <string name="wifi_connect_alert_message" msgid="8930084523889618078">"%1$s, %2$s ile bağlantı kurmak istiyor"</string>
+ <string name="wifi_connect_default_application" msgid="7143109390475484319">"Bir uygulama"</string>
<string name="wifi_p2p_dialog_title" msgid="97611782659324517">"Kablosuz Doğrudan Bağlantı"</string>
<string name="wifi_p2p_turnon_message" msgid="2909250942299627244">"Kablosuz Doğrudan Bağlantıyı başlat. Bu işlem, Kablosuz istemci/hotspot kullanımını kapatacak."</string>
<string name="wifi_p2p_failed_message" msgid="3763669677935623084">"Kablosuz Doğrudan bağlantı başlatılamadı."</string>
diff --git a/core/res/res/values-uk/strings.xml b/core/res/res/values-uk/strings.xml
index 831a03e..39be0f4 100644
--- a/core/res/res/values-uk/strings.xml
+++ b/core/res/res/values-uk/strings.xml
@@ -41,8 +41,6 @@
<string name="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g> с"</string>
<string name="durationSecond" msgid="985669622276420331">"<xliff:g id="SECONDS">%1$d</xliff:g> с"</string>
<string name="untitled" msgid="4638956954852782576">"<Без назви>"</string>
- <string name="ellipsis" msgid="7899829516048813237">"…"</string>
- <string name="ellipsis_two_dots" msgid="1228078994866030736">".."</string>
<string name="emptyPhoneNumber" msgid="7694063042079676517">"(Немає номера тел.)"</string>
<string name="unknownName" msgid="2277556546742746522">"(Невідомо)"</string>
<string name="defaultVoiceMailAlphaTag" msgid="2660020990097733077">"Голос. пошта"</string>
@@ -415,6 +413,8 @@
<string name="permdesc_bindRemoteDisplay" msgid="1261242718727295981">"Дозволяє власникові прив’язуватися до інтерфейсу верхнього рівня віддаленого екрана. Ніколи не застосовується для звичайних програм."</string>
<string name="permlab_bindRemoteViews" msgid="5697987759897367099">"прив\'язувати до служби віджетів"</string>
<string name="permdesc_bindRemoteViews" msgid="4717987810137692572">"Дозволяє власникові прив’язуватися до інтерфейсу верхнього рівня служби віджетів. Ніколи не застосовується для звичайних програм."</string>
+ <string name="permlab_bindRouteProvider" msgid="4869394607915096847">"підключитися до служби постачання маршрутів"</string>
+ <string name="permdesc_bindRouteProvider" msgid="4703804520859960329">"Дозволяє власникові підключатися до зареєстрованих постачальників маршрутів. Звичайні додатки ніколи не використовують цей дозвіл."</string>
<string name="permlab_bindDeviceAdmin" msgid="8704986163711455010">"взаємодіяти з адмін. пристрою"</string>
<string name="permdesc_bindDeviceAdmin" msgid="569715419543907930">"Дозволяє власнику надсилати задавані функції адміністратору пристрою. Ніколи не застосовується для звичайних програм."</string>
<string name="permlab_bindTvInput" msgid="5601264742478168987">"підключатися до TV-входу"</string>
@@ -742,6 +742,8 @@
<string name="permdesc_bindNotificationListenerService" msgid="985697918576902986">"Дозволяє власнику прив’язуватися до інтерфейсу верхнього рівня служби читання сповіщень. Ніколи не застосовується для звичайних програм."</string>
<string name="permlab_bindConditionProviderService" msgid="1180107672332704641">"підключитися до служби постачання умов"</string>
<string name="permdesc_bindConditionProviderService" msgid="1680513931165058425">"Додаток зможе підключатися до інтерфейсу верхнього рівня служби постачання умов. Звичайні додатки ніколи не використовують цей дозвіл."</string>
+ <string name="permlab_bindMediaRouteService" msgid="6637740382272686835">"підключатися до служби передавання медіафайлів"</string>
+ <string name="permdesc_bindMediaRouteService" msgid="6436655024972496687">"Додаток зможе підключатися до інтерфейсу верхнього рівня служби передавання медіафайлів. Звичайні додатки ніколи не використовують цей дозвіл."</string>
<string name="permlab_bindDreamService" msgid="4153646965978563462">"підключення до служби заставок"</string>
<string name="permdesc_bindDreamService" msgid="7325825272223347863">"Додаток зможе підключатися до інтерфейсу верхнього рівня служби заставок. Звичайні додатки ніколи не використовують цей дозвіл."</string>
<string name="permlab_invokeCarrierSetup" msgid="3699600833975117478">"викликати надану оператором програму конфігурації"</string>
@@ -1283,6 +1285,9 @@
<skip />
<string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"Не вдалося під’єднатися до мережі Wi-Fi"</string>
<string name="wifi_watchdog_network_disabled_detailed" msgid="5548780776418332675">" має погане з’єднання з Інтернетом."</string>
+ <string name="wifi_connect_alert_title" msgid="8455846016001810172">"Дозволити з’єднання?"</string>
+ <string name="wifi_connect_alert_message" msgid="8930084523889618078">"%1$s хоче під’єднатися до %2$s"</string>
+ <string name="wifi_connect_default_application" msgid="7143109390475484319">"Додаток"</string>
<string name="wifi_p2p_dialog_title" msgid="97611782659324517">"Wi-Fi Direct"</string>
<string name="wifi_p2p_turnon_message" msgid="2909250942299627244">"Запустити Wi-Fi Direct. Це вимкне з’єднання Wi-Fi клієнт/точка доступу."</string>
<string name="wifi_p2p_failed_message" msgid="3763669677935623084">"Не вдалося запустити Wi-Fi Direct."</string>
@@ -1776,8 +1781,7 @@
<string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Запитувати пароль перед відкріпленням"</string>
<string name="battery_saver_description" msgid="2510530476513605742">"Щоб подовжити час роботи акумулятора, функція заощадження заряду акумулятора знизить продуктивність пристрою й обмежить вібрацію та більшість фонових даних. Електронна пошта, повідомлення й інші додатки, які синхронізуються, можуть не оновлюватися, доки ви їх не відкриєте.\n\nФункція заощадження заряду акумулятора автоматично вимкнеться, коли пристрій заряджатиметься."</string>
<string name="downtime_condition_summary" msgid="8761776337475705749">"Термін простою закінчується о <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
- <!-- no translation found for downtime_condition_line_one (8762708714645352010) -->
- <skip />
+ <string name="downtime_condition_line_one" msgid="8762708714645352010">"До завершення терміну простою"</string>
<plurals name="zen_mode_duration_minutes_summary">
<item quantity="one" msgid="3177683545388923234">"Одну хвилину (до <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
<item quantity="other" msgid="2787867221129368935">"%1$d хв (до <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
@@ -1797,8 +1801,6 @@
<string name="zen_mode_until" msgid="7336308492289875088">"До <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
<string name="zen_mode_forever" msgid="4316804956488785559">"Без обмежень"</string>
<string name="toolbar_collapse_description" msgid="2821479483960330739">"Згорнути"</string>
- <!-- no translation found for zen_mode_next_alarm_summary (5915140424683747372) -->
- <skip />
- <!-- no translation found for zen_mode_next_alarm_line_one (5537042951553420916) -->
- <skip />
+ <string name="zen_mode_next_alarm_summary" msgid="5915140424683747372">"До наступного сигналу о <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
+ <string name="zen_mode_next_alarm_line_one" msgid="5537042951553420916">"До наступного сигналу"</string>
</resources>
diff --git a/core/res/res/values-ur-rPK/strings.xml b/core/res/res/values-ur-rPK/strings.xml
index 75e6317..3d42fe1 100644
--- a/core/res/res/values-ur-rPK/strings.xml
+++ b/core/res/res/values-ur-rPK/strings.xml
@@ -41,8 +41,6 @@
<string name="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g> سیکنڈ"</string>
<string name="durationSecond" msgid="985669622276420331">"<xliff:g id="SECONDS">%1$d</xliff:g> سیکنڈ"</string>
<string name="untitled" msgid="4638956954852782576">">بلا عنوان<"</string>
- <string name="ellipsis" msgid="7899829516048813237">"…"</string>
- <string name="ellipsis_two_dots" msgid="1228078994866030736">"‥"</string>
<string name="emptyPhoneNumber" msgid="7694063042079676517">"(کوئی فون نمبر نہیں ہے)"</string>
<string name="unknownName" msgid="2277556546742746522">"(نامعلوم)"</string>
<string name="defaultVoiceMailAlphaTag" msgid="2660020990097733077">"صوتی میل"</string>
@@ -415,6 +413,8 @@
<string name="permdesc_bindRemoteDisplay" msgid="1261242718727295981">"حامل کو ریموٹ ڈسپلے کے اعلی سطحی انٹرفیس کا پابند ہونے کی اجازت دیتا ہے۔ عام ایپس کیلئے کبھی بھی اس کی ضرورت نہيں ہونی چاہئے۔"</string>
<string name="permlab_bindRemoteViews" msgid="5697987759897367099">"ایک ویجیٹ سروس کے پابند بنیں"</string>
<string name="permdesc_bindRemoteViews" msgid="4717987810137692572">"حامل کو ویجیٹ سروس کے اعلی سطحی انٹرفیس کا پابند ہونے کی اجازت دیتا ہے۔ عام ایپس کیلئے کبھی بھی اس کی ضرورت نہيں ہونی چاہئے۔"</string>
+ <string name="permlab_bindRouteProvider" msgid="4869394607915096847">"راستہ فراہم کرنے والی ایک سروس کے پابند بنیں"</string>
+ <string name="permdesc_bindRouteProvider" msgid="4703804520859960329">"حامل کو کسی بھی رجسٹرڈ راستہ کے فراہم کنندگان کا پابند ہونے کی اجازت دیتا ہے۔ عام ایپس کیلئے کبھی بھی اس کی ضرورت نہيں ہونی چاہئے۔"</string>
<string name="permlab_bindDeviceAdmin" msgid="8704986163711455010">"آلہ کے ایک منتظم کے ساتھ تعامل کریں"</string>
<string name="permdesc_bindDeviceAdmin" msgid="569715419543907930">"حامل کو ایک آلہ کے منتظم کو ارادے بھیجنے دیتا ہے۔ عام ایپس کیلئے کبھی بھی اس کی ضرورت نہيں ہونی چاہئے۔"</string>
<string name="permlab_bindTvInput" msgid="5601264742478168987">"ایک TV ان پٹ کے پابند بنیں"</string>
@@ -742,6 +742,8 @@
<string name="permdesc_bindNotificationListenerService" msgid="985697918576902986">"حامل کو اطلاع سننے والی سروس کے اعلی سطحی انٹرفیس کا پابند ہونے کی اجازت دیتا ہے۔ عام ایپس کیلئے کبھی بھی اس کی ضرورت نہيں ہونی چاہئے۔"</string>
<string name="permlab_bindConditionProviderService" msgid="1180107672332704641">"شرط فراہم کرنے والی ایک سروس کے پابند بنیں"</string>
<string name="permdesc_bindConditionProviderService" msgid="1680513931165058425">"حامل کو شرط فراہم کنندہ کی سروس کے اعلی سطحی انٹرفیس کا پابند ہونے کی اجازت دیتا ہے۔ عام ایپس کیلئے کبھی بھی اس کی ضرورت نہيں ہونی چاہئے۔"</string>
+ <string name="permlab_bindMediaRouteService" msgid="6637740382272686835">"میڈیا روٹ سروس کا پابند بنیں"</string>
+ <string name="permdesc_bindMediaRouteService" msgid="6436655024972496687">"حامل کو میڈیا روٹ سروس کے اعلی سطحی انٹرفیس کا پابند کرنے کی اجازت دیتا ہے۔ معمول کی ایپس کیلئے کبھی درکار نہیں ہونا چاہئے۔"</string>
<string name="permlab_bindDreamService" msgid="4153646965978563462">"ایک ڈریم سروس کا پابند بنیں"</string>
<string name="permdesc_bindDreamService" msgid="7325825272223347863">"حامل کو ڈریم سروس کے اعلی سطحی انٹرفیس کا پابند ہونے کی اجازت دیتی ہے۔ عام ایپس کیلئے کبھی بھی اس کی ضرورت نہيں ہونی چاہیے۔"</string>
<string name="permlab_invokeCarrierSetup" msgid="3699600833975117478">"کیریئر کے ذریعے فراہم کردہ کنفگریشن ایپ طلب کریں"</string>
@@ -1283,6 +1285,9 @@
<skip />
<string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"Wi-Fi سے مربوط نہیں ہو سکا"</string>
<string name="wifi_watchdog_network_disabled_detailed" msgid="5548780776418332675">" اس میں ایک کمزور انٹرنیٹ کنکشن ہے۔"</string>
+ <string name="wifi_connect_alert_title" msgid="8455846016001810172">"کنکشن کی اجازت دیں؟"</string>
+ <string name="wifi_connect_alert_message" msgid="8930084523889618078">"%2$s سے %1$s منسلک ہونا چاہے گا"</string>
+ <string name="wifi_connect_default_application" msgid="7143109390475484319">"ایک ایپلیکیشن"</string>
<string name="wifi_p2p_dialog_title" msgid="97611782659324517">"Wi-Fi ڈائریکٹ"</string>
<string name="wifi_p2p_turnon_message" msgid="2909250942299627244">"Wi-Fi ڈائرکٹ شروع کریں۔ یہ Wi-Fi کلائنٹ/ہاٹ اسپاٹ کو آف کردے گا۔"</string>
<string name="wifi_p2p_failed_message" msgid="3763669677935623084">"Wi-Fi ڈائرکٹ شروع نہیں کرسکا۔"</string>
@@ -1776,8 +1781,7 @@
<string name="lock_to_app_unlock_password" msgid="6380979775916974414">"پن ہٹانے سے پہلے پاس ورڈ طلب کریں"</string>
<string name="battery_saver_description" msgid="2510530476513605742">"بیٹری کی میعاد بہتر بنانے میں مدد کرنے کیلئے، بیٹری سیور آپ کے آلہ کی کارکردگی میں تخفیف کر دیتی ہے اور وائبریشن اور پس منظر کے زیادہ تر ڈیٹا کو محدود کر دیتی ہے۔ ای میل، پیغام رسانی اور مطابقت پذیری پر انحصار کرنے والی دیگر ایپس ممکن ہے اس وقت تک اپ ڈیٹ نہ ہوں جب تک آپ انہیں نہ کھولیں۔\n\nآپ کا آلہ چارج ہوتے وقت بیٹری سیور خود بخود آف ہو جاتی ہے۔"</string>
<string name="downtime_condition_summary" msgid="8761776337475705749">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g> پر آپ کا آخری وقت ختم ہونے تک"</string>
- <!-- no translation found for downtime_condition_line_one (8762708714645352010) -->
- <skip />
+ <string name="downtime_condition_line_one" msgid="8762708714645352010">"آپ کا ڈاؤن ٹائم ختم ہونے تک"</string>
<plurals name="zen_mode_duration_minutes_summary">
<item quantity="one" msgid="3177683545388923234">"ایک منٹ کیلئے (<xliff:g id="FORMATTEDTIME">%2$s</xliff:g> تک)"</item>
<item quantity="other" msgid="2787867221129368935">"%1$d منٹ کیلئے (<xliff:g id="FORMATTEDTIME">%2$s</xliff:g> تک)"</item>
@@ -1797,8 +1801,6 @@
<string name="zen_mode_until" msgid="7336308492289875088">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g> تک"</string>
<string name="zen_mode_forever" msgid="4316804956488785559">"غیر متعینہ"</string>
<string name="toolbar_collapse_description" msgid="2821479483960330739">"سکیڑیں"</string>
- <!-- no translation found for zen_mode_next_alarm_summary (5915140424683747372) -->
- <skip />
- <!-- no translation found for zen_mode_next_alarm_line_one (5537042951553420916) -->
- <skip />
+ <string name="zen_mode_next_alarm_summary" msgid="5915140424683747372">"اگلے الارم تک بوقت <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
+ <string name="zen_mode_next_alarm_line_one" msgid="5537042951553420916">"اگلے الارم تک"</string>
</resources>
diff --git a/core/res/res/values-uz-rUZ/strings.xml b/core/res/res/values-uz-rUZ/strings.xml
index 27622e4..205470d 100644
--- a/core/res/res/values-uz-rUZ/strings.xml
+++ b/core/res/res/values-uz-rUZ/strings.xml
@@ -41,8 +41,6 @@
<string name="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g> soniya"</string>
<string name="durationSecond" msgid="985669622276420331">"<xliff:g id="SECONDS">%1$d</xliff:g> soniya"</string>
<string name="untitled" msgid="4638956954852782576">"<Nomsiz>"</string>
- <string name="ellipsis" msgid="7899829516048813237">"…"</string>
- <string name="ellipsis_two_dots" msgid="1228078994866030736">"‥"</string>
<string name="emptyPhoneNumber" msgid="7694063042079676517">"(Telefon raqamlari yo‘q)"</string>
<string name="unknownName" msgid="2277556546742746522">"(Noma’lum)"</string>
<string name="defaultVoiceMailAlphaTag" msgid="2660020990097733077">"Ovozli xabar"</string>
@@ -415,6 +413,8 @@
<string name="permdesc_bindRemoteDisplay" msgid="1261242718727295981">"Foydalanuvchiga masofaviy ekranning yuqori darajali interfeysini bog‘lash imkonini beradi. Oddiy dasturlar uchun hech qachon kerak bo‘lmaydi."</string>
<string name="permlab_bindRemoteViews" msgid="5697987759897367099">"vidjet xizmatiga bog‘lash"</string>
<string name="permdesc_bindRemoteViews" msgid="4717987810137692572">"Ilova vidjetlar xizmatining yuqori darajali interfeysiga ulanishi mumkin. Oddiy ilovalar uchun talab qilinmaydi."</string>
+ <string name="permlab_bindRouteProvider" msgid="4869394607915096847">"yo‘nalish taqdim etuvchilarning serveriga bog‘lanish"</string>
+ <string name="permdesc_bindRouteProvider" msgid="4703804520859960329">"Ilova ro‘yxatdan o‘tgan shartlarni taqdim etuvchilarning serveriga ulanishi mumkin. Oddiy ilovalar uchun talab qilinmaydi."</string>
<string name="permlab_bindDeviceAdmin" msgid="8704986163711455010">"administrator bilan kelishib harakat qilish"</string>
<string name="permdesc_bindDeviceAdmin" msgid="569715419543907930">"Ilova qurilma administratoriga maqsadlarni yuborishi mumkin. Oddiy ilovalar uchun talab qilinmaydi."</string>
<string name="permlab_bindTvInput" msgid="5601264742478168987">"TV-kiritishga ulanish"</string>
@@ -742,6 +742,8 @@
<string name="permdesc_bindNotificationListenerService" msgid="985697918576902986">"Foydalanuvchiga bildirishnomani eshituvchi xizmat yuqori darajali interfeysini bog‘lash imkonini beradi. Oddiy dasturlar uchun hech qachon kerak bo‘lmaydi."</string>
<string name="permlab_bindConditionProviderService" msgid="1180107672332704641">"shartlarni taqdim etuvchilarning serveriga ulanish"</string>
<string name="permdesc_bindConditionProviderService" msgid="1680513931165058425">"Ilova shartlarni taqdim etuvchining yuqori darajali interfeysiga ulanishi mumkin. Oddiy ilovalar uchun talab qilinmaydi."</string>
+ <string name="permlab_bindMediaRouteService" msgid="6637740382272686835">"media fayllarni uzatish vositasiga bog‘lab qo‘yish"</string>
+ <string name="permdesc_bindMediaRouteService" msgid="6436655024972496687">"Media fayllarni uzatishning yuqori darajali vositasiga bog‘lab qo‘yish. Oddiy ilovalar uchun talab qilinmaydi."</string>
<string name="permlab_bindDreamService" msgid="4153646965978563462">"Ekran lavhalari xizmatiga ulanish"</string>
<string name="permdesc_bindDreamService" msgid="7325825272223347863">"Ekran lavhalari xizmatining yuqori darajali interfeysiga ulanish. Oddiy ilovalar tomonidan ishlatilmaydi."</string>
<string name="permlab_invokeCarrierSetup" msgid="3699600833975117478">"aloqa operatorining sozlash dasturini so‘rash"</string>
@@ -1283,6 +1285,9 @@
<skip />
<string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"Wi-Fi’ga ulana olmadi"</string>
<string name="wifi_watchdog_network_disabled_detailed" msgid="5548780776418332675">" tezligi past Internetga ulangan."</string>
+ <string name="wifi_connect_alert_title" msgid="8455846016001810172">"Ulanishga ruxsat berilsinmi?"</string>
+ <string name="wifi_connect_alert_message" msgid="8930084523889618078">"%1$s quyidagiga ulanmoqchi: %2$s"</string>
+ <string name="wifi_connect_default_application" msgid="7143109390475484319">"Ilova"</string>
<string name="wifi_p2p_dialog_title" msgid="97611782659324517">"Wi-Fi Direct"</string>
<string name="wifi_p2p_turnon_message" msgid="2909250942299627244">"Wi-Fi Direct’ni ishga tushirish. Bu Wi-Fi mijoz/ulanish nuqtasini o‘chiradi."</string>
<string name="wifi_p2p_failed_message" msgid="3763669677935623084">"Wi-Fi Direct ishga tushirilmadi."</string>
@@ -1776,8 +1781,7 @@
<string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Bo‘shatishdan oldin parol so‘ralsin"</string>
<string name="battery_saver_description" msgid="2510530476513605742">"Batareya quvvatini uzoqroq vaqtga yetkazish uchun quvvat tejash funksiyasi qurilmangiz unumdorligini kamaytiradi hamda uning tebranishi va orqa fonda internetdan foydalanishni cheklaydi. Sinxronlanib turishi lozim bo‘lgan e-pochta, xabar almashinuv va boshqa ilovalar esa ishga tushirilmaguncha yangilanmaydi.\n\nQurilmani quvvat oldirish uchun energiya manbayiga ulashingiz bilanoq, quvvat tejash funksiyasi avtomatik tarzda o‘chadi."</string>
<string name="downtime_condition_summary" msgid="8761776337475705749">"Tanaffus vaqti tugaguncha – <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
- <!-- no translation found for downtime_condition_line_one (8762708714645352010) -->
- <skip />
+ <string name="downtime_condition_line_one" msgid="8762708714645352010">"Nofoal vaqtingiz tugaguncha"</string>
<plurals name="zen_mode_duration_minutes_summary">
<item quantity="one" msgid="3177683545388923234">"Bir daqiqa (ushbu vaqtgacha: <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
<item quantity="other" msgid="2787867221129368935">"%1$d daqiqa (ushbu vaqtgacha: <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
@@ -1797,8 +1801,6 @@
<string name="zen_mode_until" msgid="7336308492289875088">"Ushbu vaqtgacha: <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
<string name="zen_mode_forever" msgid="4316804956488785559">"Uzluksiz ravishda"</string>
<string name="toolbar_collapse_description" msgid="2821479483960330739">"Yig‘ish"</string>
- <!-- no translation found for zen_mode_next_alarm_summary (5915140424683747372) -->
- <skip />
- <!-- no translation found for zen_mode_next_alarm_line_one (5537042951553420916) -->
- <skip />
+ <string name="zen_mode_next_alarm_summary" msgid="5915140424683747372">"Keyingi uyg‘otkich vaqtigacha (<xliff:g id="FORMATTEDTIME">%1$s</xliff:g>)"</string>
+ <string name="zen_mode_next_alarm_line_one" msgid="5537042951553420916">"Keyingi uyg‘otkich vaqtigacha"</string>
</resources>
diff --git a/core/res/res/values-vi/strings.xml b/core/res/res/values-vi/strings.xml
index ed7c492..c6fdefb 100644
--- a/core/res/res/values-vi/strings.xml
+++ b/core/res/res/values-vi/strings.xml
@@ -41,8 +41,6 @@
<string name="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g> giây"</string>
<string name="durationSecond" msgid="985669622276420331">"<xliff:g id="SECONDS">%1$d</xliff:g> giây"</string>
<string name="untitled" msgid="4638956954852782576">"<Không có tiêu đề>"</string>
- <string name="ellipsis" msgid="7899829516048813237">"…"</string>
- <string name="ellipsis_two_dots" msgid="1228078994866030736">"‥"</string>
<string name="emptyPhoneNumber" msgid="7694063042079676517">"(Không có số điện thoại nào)"</string>
<string name="unknownName" msgid="2277556546742746522">"(Không xác định)"</string>
<string name="defaultVoiceMailAlphaTag" msgid="2660020990097733077">"Thư thoại"</string>
@@ -415,6 +413,8 @@
<string name="permdesc_bindRemoteDisplay" msgid="1261242718727295981">"Cho phép chủ sở hữu liên kết với giao diện cấp cao nhất của màn hình từ xa. Không cần thiết cho các ứng dụng thông thường."</string>
<string name="permlab_bindRemoteViews" msgid="5697987759897367099">"liên kết với dịch vụ tiện ích con"</string>
<string name="permdesc_bindRemoteViews" msgid="4717987810137692572">"Cho phép chủ sở hữu liên kết với giao diện cấp cao nhất của dịch vụ tiện ích con. Không cần thiết cho các ứng dụng thông thường."</string>
+ <string name="permlab_bindRouteProvider" msgid="4869394607915096847">"liên kết với dịch vụ nhà cung cấp định tuyến"</string>
+ <string name="permdesc_bindRouteProvider" msgid="4703804520859960329">"Cho phép chủ sở hữu liên kết với bất kỳ nhà cung cấp định tuyến đã đăng ký nào. Không cần thiết cho các ứng dụng thông thường."</string>
<string name="permlab_bindDeviceAdmin" msgid="8704986163711455010">"tương tác với quản trị viên thiết bị"</string>
<string name="permdesc_bindDeviceAdmin" msgid="569715419543907930">"Cho phép chủ sở hữu gửi các ý định đến quản trị viên thiết bị. Không cần thiết cho các ứng dụng thông thường."</string>
<string name="permlab_bindTvInput" msgid="5601264742478168987">"liên kết với đầu vào TV"</string>
@@ -742,6 +742,8 @@
<string name="permdesc_bindNotificationListenerService" msgid="985697918576902986">"Cho phép chủ sở hữu liên kết với giao diện cấp cao nhất của dịch vụ trình xử lý thông báo. Không cần thiết cho các ứng dụng thông thường."</string>
<string name="permlab_bindConditionProviderService" msgid="1180107672332704641">"liên kết với dịch vụ trình cung cấp điều kiện"</string>
<string name="permdesc_bindConditionProviderService" msgid="1680513931165058425">"Cho phép chủ sở hữu liên kết với giao diện cấp cao nhất của dịch vụ trình cung cấp điều kiện. Không cần thiết cho các ứng dụng thông thường."</string>
+ <string name="permlab_bindMediaRouteService" msgid="6637740382272686835">"liên kết với dịch vụ định tuyến phương tiện"</string>
+ <string name="permdesc_bindMediaRouteService" msgid="6436655024972496687">"Cho phép chủ sở hữu liên kết với giao diện cấp cao nhất của dịch vụ định tuyến phương tiện. Không cần thiết cho các ứng dụng thông thường."</string>
<string name="permlab_bindDreamService" msgid="4153646965978563462">"liên kết với dịch vụ dream"</string>
<string name="permdesc_bindDreamService" msgid="7325825272223347863">"Cho phép chủ sở hữu liên kết với giao diện cấp cao nhất của dịch vụ dream. Không cần thiết cho các ứng dụng thông thường."</string>
<string name="permlab_invokeCarrierSetup" msgid="3699600833975117478">"gọi ra ứng dụng cấu hình do nhà cung cấp dịch vụ cung cấp"</string>
@@ -1283,6 +1285,11 @@
<skip />
<string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"Không thể kết nối với Wi-Fi"</string>
<string name="wifi_watchdog_network_disabled_detailed" msgid="5548780776418332675">" có kết nối Internet không tốt."</string>
+ <string name="wifi_connect_alert_title" msgid="8455846016001810172">"Cho phép kết nối?"</string>
+ <!-- String.format failed for translation -->
+ <!-- no translation found for wifi_connect_alert_message (8930084523889618078) -->
+ <skip />
+ <string name="wifi_connect_default_application" msgid="7143109390475484319">"Ứng dụng"</string>
<string name="wifi_p2p_dialog_title" msgid="97611782659324517">"Wi-Fi Direct"</string>
<string name="wifi_p2p_turnon_message" msgid="2909250942299627244">"Khởi động Wi-Fi Direct. Việc này sẽ tắt hoạt động của ứng dụng khách/điểm phát sóng Wi-Fi."</string>
<string name="wifi_p2p_failed_message" msgid="3763669677935623084">"Không thể khởi động Wi-Fi Direct."</string>
diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml
index f04ecf6..5295601 100644
--- a/core/res/res/values-zh-rCN/strings.xml
+++ b/core/res/res/values-zh-rCN/strings.xml
@@ -41,8 +41,6 @@
<string name="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g>秒"</string>
<string name="durationSecond" msgid="985669622276420331">"<xliff:g id="SECONDS">%1$d</xliff:g>秒"</string>
<string name="untitled" msgid="4638956954852782576">"<未命名>"</string>
- <string name="ellipsis" msgid="7899829516048813237">"..."</string>
- <string name="ellipsis_two_dots" msgid="1228078994866030736">"‥"</string>
<string name="emptyPhoneNumber" msgid="7694063042079676517">"(无电话号码)"</string>
<string name="unknownName" msgid="2277556546742746522">"(未知)"</string>
<string name="defaultVoiceMailAlphaTag" msgid="2660020990097733077">"语音信箱"</string>
@@ -415,6 +413,8 @@
<string name="permdesc_bindRemoteDisplay" msgid="1261242718727295981">"允许应用绑定至远程显示屏的顶级接口。普通应用绝不需要此权限。"</string>
<string name="permlab_bindRemoteViews" msgid="5697987759897367099">"绑定到小部件服务"</string>
<string name="permdesc_bindRemoteViews" msgid="4717987810137692572">"允许应用绑定到小部件服务的顶级接口。普通应用绝不需要此权限。"</string>
+ <string name="permlab_bindRouteProvider" msgid="4869394607915096847">"绑定到路由程序服务"</string>
+ <string name="permdesc_bindRouteProvider" msgid="4703804520859960329">"允许应用绑定到任何已注册的路由程序。普通应用绝不需要此权限。"</string>
<string name="permlab_bindDeviceAdmin" msgid="8704986163711455010">"与设备管理器交互"</string>
<string name="permdesc_bindDeviceAdmin" msgid="569715419543907930">"允许应用向设备管理器发送Intent。普通应用绝不需要此权限。"</string>
<string name="permlab_bindTvInput" msgid="5601264742478168987">"绑定至电视输入设备"</string>
@@ -742,6 +742,8 @@
<string name="permdesc_bindNotificationListenerService" msgid="985697918576902986">"允许应用绑定到通知侦听器服务的顶级接口(普通应用绝不需要此权限)。"</string>
<string name="permlab_bindConditionProviderService" msgid="1180107672332704641">"绑定到条件提供程序服务"</string>
<string name="permdesc_bindConditionProviderService" msgid="1680513931165058425">"允许应用绑定到条件提供程序服务的顶级接口。普通应用绝不需要此权限。"</string>
+ <string name="permlab_bindMediaRouteService" msgid="6637740382272686835">"绑定至媒体转接服务"</string>
+ <string name="permdesc_bindMediaRouteService" msgid="6436655024972496687">"允许应用绑定至媒体转接服务的顶级接口。普通应用绝不需要此权限。"</string>
<string name="permlab_bindDreamService" msgid="4153646965978563462">"绑定到互动屏保服务"</string>
<string name="permdesc_bindDreamService" msgid="7325825272223347863">"允许应用绑定到互动屏保服务的顶级接口。普通应用绝不需要此权限。"</string>
<string name="permlab_invokeCarrierSetup" msgid="3699600833975117478">"调用运营商提供的配置应用"</string>
@@ -1283,6 +1285,9 @@
<skip />
<string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"无法连接到WLAN"</string>
<string name="wifi_watchdog_network_disabled_detailed" msgid="5548780776418332675">" 互联网连接状况不佳。"</string>
+ <string name="wifi_connect_alert_title" msgid="8455846016001810172">"要允许连接吗?"</string>
+ <string name="wifi_connect_alert_message" msgid="8930084523889618078">"%1$s想要连接到%2$s"</string>
+ <string name="wifi_connect_default_application" msgid="7143109390475484319">"一款应用"</string>
<string name="wifi_p2p_dialog_title" msgid="97611782659324517">"WLAN直连"</string>
<string name="wifi_p2p_turnon_message" msgid="2909250942299627244">"启动WLAN直连。此操作将会关闭WLAN客户端/热点。"</string>
<string name="wifi_p2p_failed_message" msgid="3763669677935623084">"无法启动WLAN直连。"</string>
@@ -1776,8 +1781,7 @@
<string name="lock_to_app_unlock_password" msgid="6380979775916974414">"取消时要求输入密码"</string>
<string name="battery_saver_description" msgid="2510530476513605742">"为了延长电池的续航时间,节电助手会降低设备的性能,并限制振动和大部分后台流量。对于电子邮件、聊天工具等依赖于同步功能的应用,可能要打开这类应用时才能收到新信息。\n\n节电助手会在设备充电时自动关闭。"</string>
<string name="downtime_condition_summary" msgid="8761776337475705749">"直到休息时间结束(<xliff:g id="FORMATTEDTIME">%1$s</xliff:g>)"</string>
- <!-- no translation found for downtime_condition_line_one (8762708714645352010) -->
- <skip />
+ <string name="downtime_condition_line_one" msgid="8762708714645352010">"到休息时间结束"</string>
<plurals name="zen_mode_duration_minutes_summary">
<item quantity="one" msgid="3177683545388923234">"1 分钟(到<xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
<item quantity="other" msgid="2787867221129368935">"%1$d 分钟(到<xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
@@ -1797,8 +1801,6 @@
<string name="zen_mode_until" msgid="7336308492289875088">"到<xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
<string name="zen_mode_forever" msgid="4316804956488785559">"无限期"</string>
<string name="toolbar_collapse_description" msgid="2821479483960330739">"收起"</string>
- <!-- no translation found for zen_mode_next_alarm_summary (5915140424683747372) -->
- <skip />
- <!-- no translation found for zen_mode_next_alarm_line_one (5537042951553420916) -->
- <skip />
+ <string name="zen_mode_next_alarm_summary" msgid="5915140424683747372">"到下次闹钟时间(<xliff:g id="FORMATTEDTIME">%1$s</xliff:g>)"</string>
+ <string name="zen_mode_next_alarm_line_one" msgid="5537042951553420916">"到下次闹钟时间"</string>
</resources>
diff --git a/core/res/res/values-zh-rHK/strings.xml b/core/res/res/values-zh-rHK/strings.xml
index 87d5172..1961070 100644
--- a/core/res/res/values-zh-rHK/strings.xml
+++ b/core/res/res/values-zh-rHK/strings.xml
@@ -41,8 +41,6 @@
<string name="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g> 秒"</string>
<string name="durationSecond" msgid="985669622276420331">"<xliff:g id="SECONDS">%1$d</xliff:g> 秒"</string>
<string name="untitled" msgid="4638956954852782576">"<未命名>"</string>
- <string name="ellipsis" msgid="7899829516048813237">"..."</string>
- <string name="ellipsis_two_dots" msgid="1228078994866030736">"‥"</string>
<string name="emptyPhoneNumber" msgid="7694063042079676517">"(沒有電話號碼)"</string>
<string name="unknownName" msgid="2277556546742746522">"(未知)"</string>
<string name="defaultVoiceMailAlphaTag" msgid="2660020990097733077">"留言信箱"</string>
@@ -415,6 +413,8 @@
<string name="permdesc_bindRemoteDisplay" msgid="1261242718727295981">"允許應用程式繫結至遠端屏螢的頂層介面 (不建議一般應用程式使用)。"</string>
<string name="permlab_bindRemoteViews" msgid="5697987759897367099">"繫結至小工具服務"</string>
<string name="permdesc_bindRemoteViews" msgid="4717987810137692572">"允許應用程式繫結至小工具服務的頂層介面 (不建議一般應用程式使用)。"</string>
+ <string name="permlab_bindRouteProvider" msgid="4869394607915096847">"繫結至路由供應商服務"</string>
+ <string name="permdesc_bindRouteProvider" msgid="4703804520859960329">"允許應用程式繫結至任何已註冊的路由供應商,但一般應用程式並不需要使用。"</string>
<string name="permlab_bindDeviceAdmin" msgid="8704986163711455010">"與裝置管理員互動"</string>
<string name="permdesc_bindDeviceAdmin" msgid="569715419543907930">"允許應用程式將調用請求傳送至裝置管理員 (不建議一般應用程式使用)。"</string>
<string name="permlab_bindTvInput" msgid="5601264742478168987">"繫結至電視訊號輸入裝置"</string>
@@ -742,6 +742,8 @@
<string name="permdesc_bindNotificationListenerService" msgid="985697918576902986">"允許應用程式繫結至通知接聽器服務的頂層介面 (不建議一般應用程式使用)。"</string>
<string name="permlab_bindConditionProviderService" msgid="1180107672332704641">"繫結至條件供應商服務"</string>
<string name="permdesc_bindConditionProviderService" msgid="1680513931165058425">"允許應用程式繫結至條件供應商服務的頂層介面,但一般應用程式並不需要使用。"</string>
+ <string name="permlab_bindMediaRouteService" msgid="6637740382272686835">"繫結至媒體轉送服務"</string>
+ <string name="permdesc_bindMediaRouteService" msgid="6436655024972496687">"允許應用程式繫結至媒體轉送服務的頂層介面,但一般應用程式並不需要使用。"</string>
<string name="permlab_bindDreamService" msgid="4153646965978563462">"繫結至 Dream 服務"</string>
<string name="permdesc_bindDreamService" msgid="7325825272223347863">"允許應用程式繫結至 Dream 服務的頂層介面 (不建議一般應用程式使用)。"</string>
<string name="permlab_invokeCarrierSetup" msgid="3699600833975117478">"調用流動網絡供應商提供的設定應用程式"</string>
@@ -1283,6 +1285,9 @@
<skip />
<string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"無法連線至 Wi-Fi"</string>
<string name="wifi_watchdog_network_disabled_detailed" msgid="5548780776418332675">" 互聯網連線欠佳。"</string>
+ <string name="wifi_connect_alert_title" msgid="8455846016001810172">"允許連線?"</string>
+ <string name="wifi_connect_alert_message" msgid="8930084523889618078">"%1$s 要求連線至 %2$s"</string>
+ <string name="wifi_connect_default_application" msgid="7143109390475484319">"應用程式"</string>
<string name="wifi_p2p_dialog_title" msgid="97611782659324517">"Wi-Fi Direct"</string>
<string name="wifi_p2p_turnon_message" msgid="2909250942299627244">"啟動 Wi-Fi Direct,這會關閉 Wi-Fi 使用者端/熱點。"</string>
<string name="wifi_p2p_failed_message" msgid="3763669677935623084">"無法啟動 Wi-Fi Direct。"</string>
@@ -1776,8 +1781,7 @@
<string name="lock_to_app_unlock_password" msgid="6380979775916974414">"取消固定時必須輸入密碼"</string>
<string name="battery_saver_description" msgid="2510530476513605742">"省電模式可延長電池使用時間,但會降低裝置的效能,並限制震動和大部分背景數據傳輸。電郵、短訊及其他需要同步處理的應用程式可能只會在開啟時才會更新。\n\n裝置充電時,省電模式會自動關閉。"</string>
<string name="downtime_condition_summary" msgid="8761776337475705749">"直到停機時間於 <xliff:g id="FORMATTEDTIME">%1$s</xliff:g> 結束"</string>
- <!-- no translation found for downtime_condition_line_one (8762708714645352010) -->
- <skip />
+ <string name="downtime_condition_line_one" msgid="8762708714645352010">"直到停機時間完結"</string>
<plurals name="zen_mode_duration_minutes_summary">
<item quantity="one" msgid="3177683545388923234">"需時 1 分鐘 (完成時間:<xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
<item quantity="other" msgid="2787867221129368935">"需時 %1$d 分鐘 (完成時間 <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
@@ -1797,8 +1801,6 @@
<string name="zen_mode_until" msgid="7336308492289875088">"完成時間:<xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
<string name="zen_mode_forever" msgid="4316804956488785559">"無限期"</string>
<string name="toolbar_collapse_description" msgid="2821479483960330739">"收合"</string>
- <!-- no translation found for zen_mode_next_alarm_summary (5915140424683747372) -->
- <skip />
- <!-- no translation found for zen_mode_next_alarm_line_one (5537042951553420916) -->
- <skip />
+ <string name="zen_mode_next_alarm_summary" msgid="5915140424683747372">"直到下一個在 <xliff:g id="FORMATTEDTIME">%1$s</xliff:g> 的鬧鐘"</string>
+ <string name="zen_mode_next_alarm_line_one" msgid="5537042951553420916">"直到下一個鬧鐘"</string>
</resources>
diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml
index 9f6e525..cae6ece 100644
--- a/core/res/res/values-zh-rTW/strings.xml
+++ b/core/res/res/values-zh-rTW/strings.xml
@@ -41,8 +41,6 @@
<string name="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g> 秒"</string>
<string name="durationSecond" msgid="985669622276420331">"<xliff:g id="SECONDS">%1$d</xliff:g> 秒"</string>
<string name="untitled" msgid="4638956954852782576">"<未命名>"</string>
- <string name="ellipsis" msgid="7899829516048813237">"…"</string>
- <string name="ellipsis_two_dots" msgid="1228078994866030736">"‥"</string>
<string name="emptyPhoneNumber" msgid="7694063042079676517">"(沒有電話號碼)"</string>
<string name="unknownName" msgid="2277556546742746522">"(不明)"</string>
<string name="defaultVoiceMailAlphaTag" msgid="2660020990097733077">"語音留言"</string>
@@ -415,6 +413,8 @@
<string name="permdesc_bindRemoteDisplay" msgid="1261242718727295981">"允許應用程式繫結至遠端螢幕的頂層介面 (一般應用程式不需使用)。"</string>
<string name="permlab_bindRemoteViews" msgid="5697987759897367099">"繫結至小工具服務"</string>
<string name="permdesc_bindRemoteViews" msgid="4717987810137692572">"允許應用程式繫結至小工具服務的頂層介面 (一般應用程式不需使用)。"</string>
+ <string name="permlab_bindRouteProvider" msgid="4869394607915096847">"繫結至路由供應商服務"</string>
+ <string name="permdesc_bindRouteProvider" msgid="4703804520859960329">"允許應用程式繫結至任何已註冊的路由供應商 (一般應用程式並不需要)。"</string>
<string name="permlab_bindDeviceAdmin" msgid="8704986163711455010">"與裝置管理員互動"</string>
<string name="permdesc_bindDeviceAdmin" msgid="569715419543907930">"允許應用程式將調用請求傳送至裝置管理員 (一般應用程式不需使用)。"</string>
<string name="permlab_bindTvInput" msgid="5601264742478168987">"繫結至電視訊號輸入裝置"</string>
@@ -742,6 +742,8 @@
<string name="permdesc_bindNotificationListenerService" msgid="985697918576902986">"允許應用程式繫結至通知接聽器服務的頂層介面 (一般應用程式不需使用)。"</string>
<string name="permlab_bindConditionProviderService" msgid="1180107672332704641">"繫結至條件提供者服務"</string>
<string name="permdesc_bindConditionProviderService" msgid="1680513931165058425">"允許應用程式繫結至條件提供者服務的頂層介面 (一般應用程式並不需要)。"</string>
+ <string name="permlab_bindMediaRouteService" msgid="6637740382272686835">"繫結至媒體轉送服務"</string>
+ <string name="permdesc_bindMediaRouteService" msgid="6436655024972496687">"允許應用程式繫結至媒體轉送服務的頂層介面 (一般應用程式並不需要)。"</string>
<string name="permlab_bindDreamService" msgid="4153646965978563462">"繫結至 Dream 服務"</string>
<string name="permdesc_bindDreamService" msgid="7325825272223347863">"允許應用程式繫結至 Dream 服務的頂層介面 (一般應用程式不需使用)。"</string>
<string name="permlab_invokeCarrierSetup" msgid="3699600833975117478">"叫用行動通訊業者提供的設定應用程式"</string>
@@ -1283,6 +1285,9 @@
<skip />
<string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"無法連線至 Wi-Fi"</string>
<string name="wifi_watchdog_network_disabled_detailed" msgid="5548780776418332675">" 的網際網路連線狀況不佳。"</string>
+ <string name="wifi_connect_alert_title" msgid="8455846016001810172">"允許連線?"</string>
+ <string name="wifi_connect_alert_message" msgid="8930084523889618078">"%1$s 要求連線至 %2$s"</string>
+ <string name="wifi_connect_default_application" msgid="7143109390475484319">"應用程式"</string>
<string name="wifi_p2p_dialog_title" msgid="97611782659324517">"Wi-Fi Direct"</string>
<string name="wifi_p2p_turnon_message" msgid="2909250942299627244">"啟動 Wi-Fi Direct 作業,這會關閉 Wi-Fi 用戶端/無線基地台作業。"</string>
<string name="wifi_p2p_failed_message" msgid="3763669677935623084">"無法啟動 Wi-Fi Direct。"</string>
@@ -1776,8 +1781,7 @@
<string name="lock_to_app_unlock_password" msgid="6380979775916974414">"取消固定時必須輸入密碼"</string>
<string name="battery_saver_description" msgid="2510530476513605742">"節約耗電量功能會降低裝置的效能,並限制震動和大多數背景資料,藉此延長電池續航力。此外,電子郵件、聊天工具和其他需要使用同步功能的應用程式若未開啟,將不會自動更新。\n\n當您為裝置充電時,節約耗電量功能會自動關閉。"</string>
<string name="downtime_condition_summary" msgid="8761776337475705749">"直到 <xliff:g id="FORMATTEDTIME">%1$s</xliff:g> 停機時間結束"</string>
- <!-- no translation found for downtime_condition_line_one (8762708714645352010) -->
- <skip />
+ <string name="downtime_condition_line_one" msgid="8762708714645352010">"到停機時間結束時"</string>
<plurals name="zen_mode_duration_minutes_summary">
<item quantity="one" msgid="3177683545388923234">"1 分鐘 (結束時間:<xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
<item quantity="other" msgid="2787867221129368935">"%1$d 分鐘 (結束時間:<xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
@@ -1797,8 +1801,6 @@
<string name="zen_mode_until" msgid="7336308492289875088">"結束時間:<xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
<string name="zen_mode_forever" msgid="4316804956488785559">"無限期"</string>
<string name="toolbar_collapse_description" msgid="2821479483960330739">"收合"</string>
- <!-- no translation found for zen_mode_next_alarm_summary (5915140424683747372) -->
- <skip />
- <!-- no translation found for zen_mode_next_alarm_line_one (5537042951553420916) -->
- <skip />
+ <string name="zen_mode_next_alarm_summary" msgid="5915140424683747372">"到下次鬧鐘鈴響時:<xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
+ <string name="zen_mode_next_alarm_line_one" msgid="5537042951553420916">"到下次鬧鐘鈴響時"</string>
</resources>
diff --git a/core/res/res/values-zu/strings.xml b/core/res/res/values-zu/strings.xml
index 39789bd8..4120a739 100644
--- a/core/res/res/values-zu/strings.xml
+++ b/core/res/res/values-zu/strings.xml
@@ -41,8 +41,6 @@
<string name="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g> amasekhondi"</string>
<string name="durationSecond" msgid="985669622276420331">"<xliff:g id="SECONDS">%1$d</xliff:g> isekhondi"</string>
<string name="untitled" msgid="4638956954852782576">"<Akunasihloko>"</string>
- <string name="ellipsis" msgid="7899829516048813237">"..."</string>
- <string name="ellipsis_two_dots" msgid="1228078994866030736">"‥"</string>
<string name="emptyPhoneNumber" msgid="7694063042079676517">"(Ayikho inombolo yefoni)"</string>
<string name="unknownName" msgid="2277556546742746522">"(Akwaziwa)"</string>
<string name="defaultVoiceMailAlphaTag" msgid="2660020990097733077">"Ivoyisimeyili"</string>
@@ -415,6 +413,8 @@
<string name="permdesc_bindRemoteDisplay" msgid="1261242718727295981">"Ivumela umbambi ukuhlanganisa isixhumi esibonakalayo esisezingeni eliphezulu sesibonisi sesilawuli kude. Akumele idingelwe izinhlelo zokusebenza ezijwayelekile."</string>
<string name="permlab_bindRemoteViews" msgid="5697987759897367099">"bophezela kube isevisi yesinqunjana"</string>
<string name="permdesc_bindRemoteViews" msgid="4717987810137692572">"Ivumela umbambi ukuhlanganisa uxhumano nomsebenzisi kwezinga eliphezulu lensizakalo yesinqunjwana. Akusoze kwadingeka kwezinhlelo zokusebenza ezivamile."</string>
+ <string name="permlab_bindRouteProvider" msgid="4869394607915096847">"bophezela kusevisi yomhlinzeki womzila"</string>
+ <string name="permdesc_bindRouteProvider" msgid="4703804520859960329">"Ivumela isibambi ukubophezela kunoma yimuphi umhlinzeki womzila obhalisiwe. Akufanele kudingeke izinhlelo zokusebenza ezivamile."</string>
<string name="permlab_bindDeviceAdmin" msgid="8704986163711455010">"xhumana nomphathi wedivaysi"</string>
<string name="permdesc_bindDeviceAdmin" msgid="569715419543907930">"Ivumela ummeli ukuthumela okuqukethwe kumphathi wedivaysi. Akusoze kwadingeka kwizinhlelo zokusebenza ezivamile."</string>
<string name="permlab_bindTvInput" msgid="5601264742478168987">"bophezela kokokufaka kwe-TV"</string>
@@ -742,6 +742,8 @@
<string name="permdesc_bindNotificationListenerService" msgid="985697918576902986">"Ivumela umbambi ukubophezela kwisixhumi esibonakalayo sezinga eliphezulu lesevisi yomlaleli wesaziso. Akusoze kwadingeka kwizinhlelo zokusebenza ezivamile."</string>
<string name="permlab_bindConditionProviderService" msgid="1180107672332704641">"hlanganisa kwisevisi yomhlinzeki wesimo"</string>
<string name="permdesc_bindConditionProviderService" msgid="1680513931165058425">"Ivumela umbambi ukuhlanganisa isixhumi esibonakalayo seleveli ephezulu sesevisi yomhlinzeki wesimo. Akufanele kudingekele izinhlelo zokusebenza ezivamile."</string>
+ <string name="permlab_bindMediaRouteService" msgid="6637740382272686835">"hlanganisela kusevisi yomzila yemidiya"</string>
+ <string name="permdesc_bindMediaRouteService" msgid="6436655024972496687">"Ivumela umbambi ukuhlanganisa kusibonisi esiphezulu sesevisi yomzila wemidiya. Akufanele kudingeke kuzinhlelo zokusebenza ezivamile."</string>
<string name="permlab_bindDreamService" msgid="4153646965978563462">"bophezela kusevisi yephupho"</string>
<string name="permdesc_bindDreamService" msgid="7325825272223347863">"Ivumela isiphathi ukuthi sibophezele ukusebenzisana kwezinga eliphezulu kwesevisi yephupho. Akumele kudingelwe izinhlelo zokusebenza ezijwayelekile."</string>
<string name="permlab_invokeCarrierSetup" msgid="3699600833975117478">"buyisela uhlelo lokusebenza lokulungiselelwa okunikezwe yinkampani yenethiwekhi"</string>
@@ -1283,6 +1285,9 @@
<skip />
<string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"Ayikwazanga ukuxhuma kwi-Wi-Fi"</string>
<string name="wifi_watchdog_network_disabled_detailed" msgid="5548780776418332675">" inoxhumano oluphansi lwe-inthanethi."</string>
+ <string name="wifi_connect_alert_title" msgid="8455846016001810172">"Vumela ukuxhumeka?"</string>
+ <string name="wifi_connect_alert_message" msgid="8930084523889618078">"U-%1$s angathanda ukuxhumeka ku-%2$s"</string>
+ <string name="wifi_connect_default_application" msgid="7143109390475484319">"Uhlelo lokusebenza"</string>
<string name="wifi_p2p_dialog_title" msgid="97611782659324517">"I-Wi-Fi Eqondile"</string>
<string name="wifi_p2p_turnon_message" msgid="2909250942299627244">"Qala ukusebenza kwe-Wi-Fi Okuqondile. Lokhu kuzocima ikhasimende le-Wi-Fi/Ukusebenza okwe-hotspot"</string>
<string name="wifi_p2p_failed_message" msgid="3763669677935623084">"Yehlulekile ukuqala i-Wi-Fi Ngqo"</string>
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index e63fc55..4f8acdb 100644
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -908,12 +908,14 @@
<!-- Theme to use for dialogs spawned from this theme. -->
<attr name="dialogTheme" format="reference" />
- <!-- Window decor layout to use in dialog mode with icons -->
+ <!-- Window decor layout to use in dialog mode with icons. -->
<attr name="dialogTitleIconsDecorLayout" format="reference" />
- <!-- Window decor layout to use in dialog mode with custom titles -->
+ <!-- Window decor layout to use in dialog mode with custom titles. -->
<attr name="dialogCustomTitleDecorLayout" format="reference" />
- <!-- Window decor layout to use in dialog mode with title only -->
+ <!-- Window decor layout to use in dialog mode with title only. -->
<attr name="dialogTitleDecorLayout" format="reference" />
+ <!-- Preferred padding for dialog content. -->
+ <attr name="dialogPreferredPadding" format="dimension" />
<!-- Theme to use for alert dialogs spawned from this theme. -->
<attr name="alertDialogTheme" format="reference" />
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 6713944..68ce666 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -467,6 +467,8 @@
<bool name="config_allowTheaterModeWakeFromKey">false</bool>
<!-- If this is true, allow wake from theater mode from motion. -->
<bool name="config_allowTheaterModeWakeFromMotion">false</bool>
+ <!-- If this is true, allow wake from theater mode from motion. -->
+ <bool name="config_allowTheaterModeWakeFromMotionWhenNotDreaming">false</bool>
<!-- If this is true, allow wake from theater mode from lid switch. -->
<bool name="config_allowTheaterModeWakeFromLidSwitch">false</bool>
<!-- If this is true, allow wake from theater mode when docked. -->
@@ -615,10 +617,10 @@
<integer name="config_triplePressOnPowerBehavior">0</integer>
<!-- Package name for default keyguard appwidget [DO NOT TRANSLATE] -->
- <string name="widget_default_package_name"></string>
+ <string name="widget_default_package_name" translatable="false"></string>
<!-- Class name for default keyguard appwidget [DO NOT TRANSLATE] -->
- <string name="widget_default_class_name"></string>
+ <string name="widget_default_class_name" translatable="false"></string>
<!-- Indicate whether the SD card is accessible without removing the battery. -->
<bool name="config_batterySdCardAccessibility">false</bool>
@@ -776,7 +778,7 @@
This needs to match the constants in
policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
-->
- <integer name="config_longPressOnHomeBehavior">1</integer>
+ <integer name="config_longPressOnHomeBehavior">0</integer>
<!-- Control the behavior when the user double-taps the home button.
0 - Nothing
@@ -1131,7 +1133,7 @@
PERSIST may improve performance by reducing how often journal blocks are
reallocated (compared to truncation) resulting in better data block locality
and less churn of the storage media. -->
- <string name="db_default_journal_mode">PERSIST</string>
+ <string name="db_default_journal_mode" translatable="false">PERSIST</string>
<!-- Maximum size of the persistent journal file in bytes.
If the journal file grows to be larger than this amount then SQLite will
@@ -1143,7 +1145,7 @@
NORMAL also preserves durability in non-WAL modes and uses checksums to ensure
integrity although there is a small chance that an error might go unnoticed.
Choices are: FULL, NORMAL, OFF. -->
- <string name="db_default_sync_mode">FULL</string>
+ <string name="db_default_sync_mode" translatable="false">FULL</string>
<!-- The database synchronization mode when using Write-Ahead Logging.
FULL is safest and preserves durability at the cost of extra fsyncs.
@@ -1151,7 +1153,7 @@
and after checkpoint operations. If checkpoints are infrequent and power loss
occurs, then committed transactions could be lost and applications might break.
Choices are: FULL, NORMAL, OFF. -->
- <string name="db_wal_sync_mode">FULL</string>
+ <string name="db_wal_sync_mode" translatable="false">FULL</string>
<!-- The Write-Ahead Log auto-checkpoint interval in database pages (typically 1 to 4KB).
The log is checkpointed automatically whenever it exceeds this many pages.
@@ -1336,7 +1338,7 @@
<!-- If supported and enabled, are dreams activated when asleep and charging? (by default) -->
<bool name="config_dreamsActivatedOnSleepByDefault">false</bool>
<!-- ComponentName of the default dream (Settings.Secure.DEFAULT_SCREENSAVER_COMPONENT) -->
- <string name="config_dreamsDefaultComponent">com.google.android.deskclock/com.android.deskclock.Screensaver</string>
+ <string name="config_dreamsDefaultComponent" translatable="false">com.google.android.deskclock/com.android.deskclock.Screensaver</string>
<!-- Are we allowed to dream while not plugged in? -->
<bool name="config_dreamsEnabledOnBattery">false</bool>
@@ -1617,17 +1619,17 @@
<!-- Class name of the framework account picker activity.
Can be customized for other product types -->
- <string name="config_chooseAccountActivity"
+ <string name="config_chooseAccountActivity" translatable="false"
>android/android.accounts.ChooseAccountActivity</string>
<!-- Class name of the account type and account picker activity.
Can be customized for other product types -->
- <string name="config_chooseTypeAndAccountActivity"
+ <string name="config_chooseTypeAndAccountActivity" translatable="false"
>android/android.accounts.ChooseTypeAndAccountActivity</string>
<!-- Component name of a custom ResolverActivity (Intent resolver) to be used instead of
the default framework version. If left empty, then the framework version will be used.
Example: com.google.android.myapp/.resolver.MyResolverActivity -->
- <string name="config_customResolverActivity"></string>
+ <string name="config_customResolverActivity" translatable="false"></string>
<!-- Name of the activity or service that prompts the user to reject, accept, or whitelist
an adb host's public key, when an unwhitelisted host connects to the local adbd.
@@ -1640,7 +1642,7 @@
>com.android.vpndialogs/com.android.vpndialogs.ConfirmDialog</string>
<!-- Apps that are authorized to access shared accounts, overridden by product overlays -->
- <string name="config_appsAuthorizedForSharedAccounts">;com.android.settings;</string>
+ <string name="config_appsAuthorizedForSharedAccounts" translatable="false">;com.android.settings;</string>
<!-- Flag indicating that the media framework should not allow changes or mute on any
stream or master volumes. -->
diff --git a/core/res/res/values/dimens.xml b/core/res/res/values/dimens.xml
index 71f66ba..13e3be5 100644
--- a/core/res/res/values/dimens.xml
+++ b/core/res/res/values/dimens.xml
@@ -123,6 +123,9 @@
be either a fraction or a dimension. -->
<item type="dimen" name="dialog_min_width_minor">95%</item>
+ <!-- Default padding for dialogs. -->
+ <dimen name="dialog_padding">16dp</dimen>
+
<!-- The width of the big icons in notifications. -->
<dimen name="notification_large_icon_width">64dp</dimen>
<!-- The width of the big icons in notifications. -->
diff --git a/core/res/res/values/dimens_material.xml b/core/res/res/values/dimens_material.xml
index 515922d..4a2119b 100644
--- a/core/res/res/values/dimens_material.xml
+++ b/core/res/res/values/dimens_material.xml
@@ -91,6 +91,6 @@
<!-- Default rounded corner for controls -->
<dimen name="control_corner_material">2dp</dimen>
- <dimen name="alert_dialog_padding_material">24dp</dimen>
- <dimen name="alert_dialog_padding_top_material">18dp</dimen>
+ <dimen name="dialog_padding_material">24dp</dimen>
+ <dimen name="dialog_padding_top_material">18dp</dimen>
</resources>
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index c0a5ab2..c661c33 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -2599,5 +2599,6 @@
<public type="attr" name="collapseContentDescription"/>
<public type="attr" name="accessibilityTraversalBefore" />
<public type="attr" name="accessibilityTraversalAfter" />
+ <public type="attr" name="dialogPreferredPadding" />
</resources>
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index fe87919..17875e2 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -82,14 +82,6 @@
for a note with no name. -->
<string name="untitled"><Untitled></string>
- <!-- Used to replace a range of characters in text that is too wide
- for the space allocated to it (three dots). -->
- <string name="ellipsis">\u2026</string>
-
- <!-- Used to replace a range of characters in text that is too wide
- for the space allocated to it (two dots). -->
- <string name="ellipsis_two_dots">\u2025</string>
-
<!-- How to display the lack of a phone number -->
<string name="emptyPhoneNumber">(No phone number)</string>
@@ -326,6 +318,8 @@
<!-- If MMS discovers there isn't much space left on the device, it will show a toast with this message. -->
<string name="low_memory" product="watch">Watch storage is full. Delete some files to free space.</string>
<!-- If MMS discovers there isn't much space left on the device, it will show a toast with this message. -->
+ <string name="low_memory" product="tv">TV storage is full. Delete some files to free space.</string>
+ <!-- If MMS discovers there isn't much space left on the device, it will show a toast with this message. -->
<string name="low_memory" product="default">Phone storage is full. Delete some files to free space.</string>
<!-- SSL CA cert notification --> <skip />
@@ -348,6 +342,8 @@
<!-- Title for the Phone Options dialog to lock the screen, turn off the phone etc. -->
<string name="power_dialog" product="tablet">Tablet options</string>
<!-- Title for the Phone Options dialog to lock the screen, turn off the phone etc. -->
+ <string name="power_dialog" product="tv">TV options</string>
+ <!-- Title for the Phone Options dialog to lock the screen, turn off the phone etc. -->
<string name="power_dialog" product="default">Phone options</string>
<!-- Button to turn on silent mode, within the Phone Options dialog -->
<string name="silent_mode">Silent mode</string>
@@ -372,6 +368,9 @@
<!-- Shutdown Confirmation Dialog. When the user chooses to power off the phone, there will
be a confirmation dialog. This is the message. -->
<string name="shutdown_confirm" product="tablet">Your tablet will shut down.</string>
+ <!-- Shutdown Confirmation Dialog. When the user chooses to power off the TV, there will
+ be a confirmation dialog. This is the message. -->
+ <string name="shutdown_confirm" product="tv">Your TV will shut down.</string>
<!-- Shutdown Confirmation Dialog. When the user chooses to power off the watch, there will
be a confirmation dialog. This is the message. -->
<string name="shutdown_confirm" product="watch">Your watch will shut down.</string>
@@ -408,6 +407,8 @@
<!-- Title of the Global Actions Dialog -->
<string name="global_actions" product="tablet">Tablet options</string>
<!-- Title of the Global Actions Dialog -->
+ <string name="global_actions" product="tv">TV options</string>
+ <!-- Title of the Global Actions Dialog -->
<string name="global_actions" product="default">Phone options</string>
<!-- label for item that locks the phone in the phone options dialog -->
@@ -745,6 +746,10 @@
messages stored on your tablet or SIM card. This allows the app to read all
SMS messages, regardless of content or confidentiality.</string>
<!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
+ <string name="permdesc_readSms" product="tv">Allows the app to read SMS
+ messages stored on your TV or SIM card. This allows the app to read all
+ SMS messages, regardless of content or confidentiality.</string>
+ <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
<string name="permdesc_readSms" product="default">Allows the app to read SMS
messages stored on your phone or SIM card. This allows the app to read all
SMS messages, regardless of content or confidentiality.</string>
@@ -756,6 +761,10 @@
to SMS messages stored on your tablet or SIM card. Malicious apps
may delete your messages.</string>
<!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
+ <string name="permdesc_writeSms" product="tv">Allows the app to write
+ to SMS messages stored on your TV or SIM card. Malicious apps
+ may delete your messages.</string>
+ <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
<string name="permdesc_writeSms" product="default">Allows the app to write
to SMS messages stored on your phone or SIM card. Malicious apps
may delete your messages.</string>
@@ -1077,6 +1086,10 @@
its own input events (key presses, etc.) to other apps. Malicious
apps may use this to take over the tablet.</string>
<!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
+ <string name="permdesc_injectEvents" product="tv">Allows the app to deliver
+ its own input events (key presses, etc.) to other apps. Malicious
+ apps may use this to take over the TV.</string>
+ <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
<string name="permdesc_injectEvents" product="default">Allows the app to deliver
its own input events (key presses, etc.) to other apps. Malicious
apps may use this to take over the phone.</string>
@@ -1163,6 +1176,12 @@
interface of a widget service. Should never be needed for normal apps.</string>
<!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
+ <string name="permlab_bindRouteProvider">bind to a route provider service</string>
+ <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
+ <string name="permdesc_bindRouteProvider">Allows the holder to bind to any registered
+ route providers. Should never be needed for normal apps.</string>
+
+ <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
<string name="permlab_bindDeviceAdmin">interact with a device admin</string>
<!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
<string name="permdesc_bindDeviceAdmin">Allows the holder to send intents to
@@ -1216,6 +1235,8 @@
<string name="permlab_persistentActivity">make app always run</string>
<!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
<string name="permdesc_persistentActivity" product="tablet">Allows the app to make parts of itself persistent in memory. This can limit memory available to other apps slowing down the tablet.</string>
+ <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
+ <string name="permdesc_persistentActivity" product="tv">Allows the app to make parts of itself persistent in memory. This can limit memory available to other apps slowing down the TV.</string>
<string name="permdesc_persistentActivity" product="default">Allows the app to make parts of itself persistent in memory. This can limit memory available to other apps slowing down the phone.</string>
<!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
@@ -1253,6 +1274,10 @@
by deleting files in the cache directories of other applications. This may cause other
applications to start up more slowly as they need to re-retrieve their data.</string>
<!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
+ <string name="permdesc_clearAppCache" product="tv">Allows the app to free TV storage
+ by deleting files in the cache directories of other applications. This may cause other
+ applications to start up more slowly as they need to re-retrieve their data.</string>
+ <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
<string name="permdesc_clearAppCache" product="default">Allows the app to free phone storage
by deleting files in the cache directories of other applications. This may cause other
applications to start up more slowly as they need to re-retrieve their data.</string>
@@ -1270,6 +1295,11 @@
information about what you are doing with the tablet, potentially
including personal or private information.</string>
<!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
+ <string name="permdesc_readLogs" product="tv">Allows the app to read from the
+ system\'s various log files. This allows it to discover general
+ information about what you are doing with the TV, potentially
+ including personal or private information.</string>
+ <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
<string name="permdesc_readLogs" product="default">Allows the app to read from the
system\'s various log files. This allows it to discover general
information about what you are doing with the phone, potentially
@@ -1312,6 +1342,12 @@
possible to get app components into an unusable, inconsistent, or unstable state.
</string>
<!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
+ <string name="permdesc_changeComponentState" product="tv">Allows the app to change whether a
+ component of another app is enabled or not. Malicious apps may use this
+ to disable important TV capabilities. Care must be used with this permission, as it is
+ possible to get app components into an unusable, inconsistent, or unstable state.
+ </string>
+ <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
<string name="permdesc_changeComponentState" product="default">Allows the app to change whether a
component of another app is enabled or not. Malicious apps may use this
to disable important phone capabilities. Care must be used with this permission, as it is
@@ -1359,6 +1395,11 @@
This can make it take longer to start the tablet and allow the
app to slow down the overall tablet by always running.</string>
<!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
+ <string name="permdesc_receiveBootCompleted" product="tv">Allows the app to
+ have itself started as soon as the system has finished booting.
+ This can make it take longer to start the TV and allow the
+ app to slow down the overall tablet by always running.</string>
+ <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
<string name="permdesc_receiveBootCompleted" product="default">Allows the app to
have itself started as soon as the system has finished booting.
This can make it take longer to start the phone and allow the
@@ -1372,6 +1413,11 @@
may make the tablet slow or unstable by causing it to use too much memory.
</string>
<!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
+ <string name="permdesc_broadcastSticky" product="tv">Allows the app to
+ send sticky broadcasts, which remain after the broadcast ends. Excessive use
+ may make the TV slow or unstable by causing it to use too much memory.
+ </string>
+ <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
<string name="permdesc_broadcastSticky" product="default">Allows the app to
send sticky broadcasts, which remain after the broadcast ends. Excessive
use may make the phone slow or unstable by causing it to use too
@@ -1387,6 +1433,13 @@
data, and malicious apps may share contact data without your
knowledge.</string>
<!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
+ <string name="permdesc_readContacts" product="tv">Allows the app to read
+ data about your contacts stored on your TV, including the frequency
+ with which you\'ve called, emailed, or communicated in other ways with
+ specific individuals. This permission allows apps to save your contact
+ data, and malicious apps may share contact data without your
+ knowledge.</string>
+ <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
<string name="permdesc_readContacts" product="default">Allows the app to
read data about your contacts stored on your phone, including the
frequency with which you\'ve called, emailed, or communicated in other ways
@@ -1403,6 +1456,12 @@
with specific contacts. This permission allows apps to delete contact
data.</string>
<!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
+ <string name="permdesc_writeContacts" product="tv">Allows the app to
+ modify the data about your contacts stored on your TV, including the
+ frequency with which you\'ve called, emailed, or communicated in other ways
+ with specific contacts. This permission allows apps to delete contact
+ data.</string>
+ <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
<string name="permdesc_writeContacts" product="default">Allows the app to
modify the data about your contacts stored on your phone, including the
frequency with which you\'ve called, emailed, or communicated in other ways
@@ -1417,6 +1476,11 @@
This permission allows apps to save your call log data, and malicious apps
may share call log data without your knowledge.</string>
<!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
+ <string name="permdesc_readCallLog" product="tv">Allows the app to read
+ your TV\'s call log, including data about incoming and outgoing calls.
+ This permission allows apps to save your call log data, and malicious apps
+ may share call log data without your knowledge.</string>
+ <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
<string name="permdesc_readCallLog" product="default">Allows the app to read
your phone\'s call log, including data about incoming and outgoing calls.
This permission allows apps to save your call log data, and malicious apps
@@ -1428,6 +1492,9 @@
<string name="permdesc_writeCallLog" product="tablet">Allows the app to modify your tablet\'s call log, including data about incoming and outgoing calls.
Malicious apps may use this to erase or modify your call log.</string>
<!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
+ <string name="permdesc_writeCallLog" product="tv">Allows the app to modify your TV\'s call log, including data about incoming and outgoing calls.
+ Malicious apps may use this to erase or modify your call log.</string>
+ <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
<string name="permdesc_writeCallLog" product="default">Allows the app to modify your phone\'s call log, including data about incoming and outgoing calls.
Malicious apps may use this to erase or modify your call log.</string>
@@ -1475,12 +1542,16 @@
<!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
<string name="permlab_readCalendar">read calendar events plus confidential information</string>
<!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
-
<string name="permdesc_readCalendar" product="tablet">Allows the app to read
all calendar events stored on your tablet, including those of friends or
co-workers. This may allow the app to share or save your calendar data,
regardless of confidentiality or sensitivity.</string>
<!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
+ <string name="permdesc_readCalendar" product="tv">Allows the app to read
+ all calendar events stored on your TV, including those of friends or
+ co-workers. This may allow the app to share or save your calendar data,
+ regardless of confidentiality or sensitivity.</string>
+ <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
<string name="permdesc_readCalendar" product="default">Allows the app to
read all calendar events stored on your phone, including those of friends
or co-workers. This may allow the app to share or save your calendar data,
@@ -1489,17 +1560,23 @@
<!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
<string name="permlab_writeCalendar">add or modify calendar events and send email to guests without owners\' knowledge</string>
<!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
-
-<string name="permdesc_writeCalendar" product="tablet">Allows the app to
- add, remove, change events that you can modify on your tablet, including
- those of friends or co-workers. This may allow the app to send messages
- that appear to come from calendar owners, or modify events without the
- owners\' knowledge.</string>
-<string name="permdesc_writeCalendar" product="default">Allows the app to
- add, remove, change events that you can modify on your phone, including
- those of friends or co-workers. This may allow the app to send messages
- that appear to come from calendar owners, or modify events without the
- owners\' knowledge.</string>
+ <string name="permdesc_writeCalendar" product="tablet">Allows the app to
+ add, remove, change events that you can modify on your tablet, including
+ those of friends or co-workers. This may allow the app to send messages
+ that appear to come from calendar owners, or modify events without the
+ owners\' knowledge.</string>
+ <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
+ <string name="permdesc_writeCalendar" product="tv">Allows the app to
+ add, remove, change events that you can modify on your TV, including
+ those of friends or co-workers. This may allow the app to send messages
+ that appear to come from calendar owners, or modify events without the
+ owners\' knowledge.</string>
+ <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
+ <string name="permdesc_writeCalendar" product="default">Allows the app to
+ add, remove, change events that you can modify on your phone, including
+ those of friends or co-workers. This may allow the app to send messages
+ that appear to come from calendar owners, or modify events without the
+ owners\' knowledge.</string>
<!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
@@ -1635,21 +1712,30 @@
<!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
<string name="permlab_brick" product="tablet">permanently disable tablet</string>
<!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
+ <string name="permlab_brick" product="tv">permanently disable TV</string>
+ <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
<string name="permlab_brick" product="default">permanently disable phone</string>
<!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
<string name="permdesc_brick" product="tablet">Allows the app to
disable the entire tablet permanently. This is very dangerous.</string>
<!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
+ <string name="permdesc_brick" product="tv">Allows the app to
+ disable the entire TV permanently. This is very dangerous.</string>
+ <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
<string name="permdesc_brick" product="default">Allows the app to
disable the entire phone permanently. This is very dangerous.</string>
<!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
<string name="permlab_reboot" product="tablet">force tablet reboot</string>
<!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
+ <string name="permlab_reboot" product="tv">force TV reboot</string>
+ <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
<string name="permlab_reboot" product="default">force phone reboot</string>
<!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
<string name="permdesc_reboot" product="tablet">Allows the app to force the tablet to reboot.</string>
<!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
+ <string name="permdesc_reboot" product="tv">Allows the app to force the TV to reboot.</string>
+ <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
<string name="permdesc_reboot" product="default">Allows the app to force the phone to reboot.</string>
@@ -1744,6 +1830,8 @@
<!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
<string name="permlab_performCdmaProvisioning" product="tablet">directly start CDMA tablet setup</string>
<!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
+ <string name="permlab_performCdmaProvisioning" product="tv">directly start CDMA TV setup</string>
+ <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
<string name="permlab_performCdmaProvisioning" product="default">directly start CDMA phone setup</string>
<!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
<string name="permdesc_performCdmaProvisioning">Allows the app to start CDMA provisioning.
@@ -1797,10 +1885,14 @@
<!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
<string name="permlab_wakeLock" product="tablet">prevent tablet from sleeping</string>
<!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
+ <string name="permlab_wakeLock" product="tv">prevent TV from sleeping</string>
+ <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
<string name="permlab_wakeLock" product="default">prevent phone from sleeping</string>
<!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
<string name="permdesc_wakeLock" product="tablet">Allows the app to prevent the tablet from going to sleep.</string>
<!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
+ <string name="permdesc_wakeLock" product="tv">Allows the app to prevent the TV from going to sleep.</string>
+ <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
<string name="permdesc_wakeLock" product="default">Allows the app to prevent the phone from going to sleep.</string>
<!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
@@ -1808,17 +1900,24 @@
<!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
<string name="permdesc_transmitIr" product="tablet">Allows the app to use the tablet\'s infrared transmitter.</string>
<!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
+ <string name="permdesc_transmitIr" product="tv">Allows the app to use the TV\'s infrared transmitter.</string>
+ <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
<string name="permdesc_transmitIr" product="default">Allows the app to use the phone\'s infrared transmitter.</string>
<!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
<string name="permlab_devicePower" product="tablet">power tablet on or off</string>
<!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
+ <string name="permlab_devicePower" product="tv">power TV on or off</string>
+ <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
<string name="permlab_devicePower" product="default">power phone on or off</string>
<!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
<string name="permdesc_devicePower" product="tablet">Allows the app to turn the
tablet on or off.</string>
<!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
+ <string name="permdesc_devicePower" product="tv">Allows the app to turn the
+ TV on or off.</string>
+ <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
<string name="permdesc_devicePower" product="default">Allows the app to turn the phone on or off.</string>
<!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
@@ -1833,6 +1932,10 @@
allowing complete access to the tablet hardware. Only available
when a tablet is running in manufacturer test mode.</string>
<!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
+ <string name="permdesc_factoryTest" product="tv">Run as a low-level manufacturer test,
+ allowing complete access to the TV hardware. Only available
+ when a TV is running in manufacturer test mode.</string>
+ <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
<string name="permdesc_factoryTest" product="default">Run as a low-level manufacturer test,
allowing complete access to the phone hardware. Only available
when a phone is running in manufacturer test mode.</string>
@@ -1859,6 +1962,8 @@
<!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
<string name="permdesc_setTime" product="tablet">Allows the app to change the tablet\'s clock time.</string>
<!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
+ <string name="permdesc_setTime" product="tv">Allows the app to change the TV\'s clock time.</string>
+ <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
<string name="permdesc_setTime" product="default">Allows the app to change the phone\'s clock time.</string>
<!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
@@ -1866,6 +1971,8 @@
<!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
<string name="permdesc_setTimeZone" product="tablet">Allows the app to change the tablet\'s time zone.</string>
<!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
+ <string name="permdesc_setTimeZone" product="tv">Allows the app to change the TV\'s time zone.</string>
+ <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
<string name="permdesc_setTimeZone" product="default">Allows the app to change the phone\'s time zone.</string>
<!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
@@ -1880,6 +1987,10 @@
the list of accounts known by the tablet. This may include any accounts
created by applications you have installed.</string>
<!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
+ <string name="permdesc_getAccounts" product="tv">Allows the app to get
+ the list of accounts known by the TV. This may include any accounts
+ created by applications you have installed.</string>
+ <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
<string name="permdesc_getAccounts" product="default">Allows the app to get
the list of accounts known by the phone. This may include any accounts
created by applications you have installed.</string>
@@ -1961,6 +2072,10 @@
<string name="permdesc_changeWifiMulticastState" product="tablet">Allows the app to receive
packets sent to all devices on a Wi-Fi network using multicast addresses,
not just your tablet. It uses more power than the non-multicast mode.</string>
+ <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
+ <string name="permdesc_changeWifiMulticastState" product="tv">Allows the app to receive
+ packets sent to all devices on a Wi-Fi network using multicast addresses,
+ not just your TV. It uses more power than the non-multicast mode.</string>
<string name="permdesc_changeWifiMulticastState" product="default">Allows the app to receive
packets sent to all devices on a Wi-Fi network using multicast addresses,
not just your phone. It uses more power than the non-multicast mode.</string>
@@ -1972,6 +2087,10 @@
configure the local Bluetooth tablet, and to discover and pair with remote
devices.</string>
<!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
+ <string name="permdesc_bluetoothAdmin" product="tv">Allows the app to
+ configure the local Bluetooth TV, and to discover and pair with remote
+ devices.</string>
+ <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
<string name="permdesc_bluetoothAdmin" product="default">Allows the app to configure
the local Bluetooth phone, and to discover and pair with remote devices.</string>
@@ -1981,6 +2100,9 @@
<string name="permdesc_bluetoothPriv" product="tablet">Allows the app to
pair with remote devices without user interaction.</string>
<!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
+ <string name="permdesc_bluetoothPriv" product="tv">Allows the app to
+ pair with remote devices without user interaction.</string>
+ <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
<string name="permdesc_bluetoothPriv" product="default">Allows the app to
pair with remote devices without user interaction.</string>
@@ -1989,6 +2111,8 @@
<!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
<string name="permdesc_bluetoothMap" product="tablet">Allows the app to access Bluetooth MAP data.</string>
<!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
+ <string name="permdesc_bluetoothMap" product="tv">Allows the app to access Bluetooth MAP data.</string>
+ <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
<string name="permdesc_bluetoothMap" product="default">Allows the app to access Bluetooth MAP data.</string>
<string name="permlab_accessWimaxState">connect and disconnect from WiMAX</string>
@@ -1999,6 +2123,8 @@
<string name="permlab_changeWimaxState">Change WiMAX state</string>
<string name="permdesc_changeWimaxState" product="tablet">Allows the app to
connect the tablet to and disconnect the tablet from WiMAX networks.</string>
+ <string name="permdesc_changeWimaxState" product="tv">Allows the app to
+ connect the TV to and disconnect the TV from WiMAX networks.</string>
<string name="permdesc_changeWimaxState" product="default">Allows the app to
connect the phone to and disconnect the phone from WiMAX networks.</string>
@@ -2008,6 +2134,9 @@
<string name="permdesc_scoreNetworks" product="tablet">Allows the app to
rank networks and influence which networks the tablet should prefer.</string>
<!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
+ <string name="permdesc_scoreNetworks" product="tv">Allows the app to
+ rank networks and influence which networks the TV should prefer.</string>
+ <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
<string name="permdesc_scoreNetworks" product="default">Allows the app to
rank networks and influence which networks the phone should prefer.</string>
@@ -2018,6 +2147,10 @@
configuration of Bluetooth on the tablet, and to make and accept
connections with paired devices.</string>
<!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
+ <string name="permdesc_bluetooth" product="tv">Allows the app to view the
+ configuration of Bluetooth on the TV, and to make and accept
+ connections with paired devices.</string>
+ <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
<string name="permdesc_bluetooth" product="default">Allows the app to view the
configuration of the Bluetooth on the phone, and to make and accept
connections with paired devices.</string>
@@ -2178,6 +2311,11 @@
<string name="permdesc_bindConditionProviderService">Allows the holder to bind to the top-level interface of a condition provider service. Should never be needed for normal apps.</string>
<!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
+ <string name="permlab_bindMediaRouteService">bind to a media route service</string>
+ <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
+ <string name="permdesc_bindMediaRouteService">Allows the holder to bind to the top-level interface of a media route service. Should never be needed for normal apps.</string>
+
+ <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
<string name="permlab_bindDreamService">bind to a dream service</string>
<!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
<string name="permdesc_bindDreamService">Allows the holder to bind to the top-level interface of a dream service. Should never be needed for normal apps.</string>
@@ -2222,6 +2360,10 @@
typed when unlocking the screen, and lock the tablet or erase all the tablet\'s
data if too many incorrect passwords are typed.</string>
<!-- Description of policy access to watch user login attempts -->
+ <string name="policydesc_watchLogin" product="TV">Monitor the number of incorrect passwords
+ typed when unlocking the screen, and lock the TV or erase all the TV\'s
+ data if too many incorrect passwords are typed.</string>
+ <!-- Description of policy access to watch user login attempts -->
<string name="policydesc_watchLogin" product="default">Monitor the number of incorrect passwords
typed. when unlocking the screen, and lock the phone or erase all the phone\'s
data if too many incorrect passwords are typed.</string>
@@ -2238,6 +2380,8 @@
<!-- Description of policy access to wipe the user's data -->
<string name="policydesc_wipeData" product="tablet">Erase the tablet\'s data without warning by performing a factory data reset.</string>
<!-- Description of policy access to wipe the user's data -->
+ <string name="policydesc_wipeData" product="tv">Erase the TV\'s data without warning by performing a factory data reset.</string>
+ <!-- Description of policy access to wipe the user's data -->
<string name="policydesc_wipeData" product="default">Erase the phone\'s data without warning by performing a factory data reset.</string>
<string name="policylab_setGlobalProxy">Set the device global proxy</string>
<!-- Description of policy access to wipe the user's data -->
@@ -2545,6 +2689,8 @@
<!-- Shown in the lock screen when there is no SIM card. -->
<string name="lockscreen_missing_sim_message" product="tablet">No SIM card in tablet.</string>
<!-- Shown in the lock screen when there is no SIM card. -->
+ <string name="lockscreen_missing_sim_message" product="tv">No SIM card in TV.</string>
+ <!-- Shown in the lock screen when there is no SIM card. -->
<string name="lockscreen_missing_sim_message" product="default">No SIM card in phone.</string>
<!-- Shown in the lock screen to ask the user to insert a SIM card. -->
<string name="lockscreen_missing_sim_instructions">Insert a SIM card.</string>
@@ -2625,6 +2771,15 @@
<!-- For the unlock screen, informational message shown in dialog when user is almost at the limit
where they will be locked out and may have to enter an alternate username/password to unlock the phone -->
+ <string name="lockscreen_failed_attempts_almost_glogin" product="tv">
+ You have incorrectly drawn your unlock pattern <xliff:g id="number">%d</xliff:g> times.
+ After <xliff:g id="number">%d</xliff:g> more unsuccessful attempts,
+ you will be asked to unlock your TV using your Google signin.\n\n
+ Try again in <xliff:g id="number">%d</xliff:g> seconds.
+ </string>
+
+ <!-- For the unlock screen, informational message shown in dialog when user is almost at the limit
+ where they will be locked out and may have to enter an alternate username/password to unlock the phone -->
<string name="lockscreen_failed_attempts_almost_glogin" product="default">
You have incorrectly drawn your unlock pattern <xliff:g id="number">%d</xliff:g> times.
After <xliff:g id="number">%d</xliff:g> more unsuccessful attempts,
@@ -2642,6 +2797,14 @@
<!-- For the unlock screen, informational message shown in dialog when user is almost at the limit
where the device will be wiped. -->
+ <string name="lockscreen_failed_attempts_almost_at_wipe" product="tv">
+ You have incorrectly attempted to unlock the TV <xliff:g id="number">%d</xliff:g> times.
+ After <xliff:g id="number">%d</xliff:g> more unsuccessful attempts,
+ the TV will be reset to factory default and all user data will be lost.
+ </string>
+
+ <!-- For the unlock screen, informational message shown in dialog when user is almost at the limit
+ where the device will be wiped. -->
<string name="lockscreen_failed_attempts_almost_at_wipe" product="default">
You have incorrectly attempted to unlock the phone <xliff:g id="number">%d</xliff:g> times.
After <xliff:g id="number">%d</xliff:g> more unsuccessful attempts,
@@ -2657,6 +2820,13 @@
<!-- For the unlock screen, informational message shown in dialog when user has exceeded the
maximum attempts and the device will now be wiped -->
+ <string name="lockscreen_failed_attempts_now_wiping" product="tv">
+ You have incorrectly attempted to unlock the TV <xliff:g id="number">%d</xliff:g> times.
+ The TV will now be reset to factory default.
+ </string>
+
+ <!-- For the unlock screen, informational message shown in dialog when user has exceeded the
+ maximum attempts and the device will now be wiped -->
<string name="lockscreen_failed_attempts_now_wiping" product="default">
You have incorrectly attempted to unlock the phone <xliff:g id="number">%d</xliff:g> times.
The phone will now be reset to factory default.
@@ -3010,6 +3180,13 @@
applications with web browsing capabilities.</string>
<!-- Description of an application permission, listed so the user can choose whether
they want to allow the application to do this. -->
+ <string name="permdesc_writeHistoryBookmarks" product="tv">Allows the
+ app to modify the Browser\'s history or bookmarks stored on your TV.
+ This may allow the app to erase or modify Browser data. Note: this
+ permission may note be enforced by third-party browsers or other
+ applications with web browsing capabilities.</string>
+ <!-- Description of an application permission, listed so the user can choose whether
+ they want to allow the application to do this. -->
<string name="permdesc_writeHistoryBookmarks" product="default">Allows the
app to modify the Browser\'s history or bookmarks stored on your phone.
This may allow the app to erase or modify Browser data. Note:
@@ -3626,6 +3803,14 @@
<!-- Do not translate. Default access point SSID used for tethering -->
<string name="wifi_tether_configure_ssid_default" translatable="false">AndroidAP</string>
+ <!-- A notification is shown the first time a connection is attempted on an app owned AP -->
+ <!-- title for this message -->
+ <string name="wifi_connect_alert_title">Allow connection?</string>
+ <!-- message explaining who is connecting to what -->
+ <string name="wifi_connect_alert_message">%1$s would like to connect to %2$s</string>
+ <!-- default application in case name can not be found -->
+ <string name="wifi_connect_default_application">An application</string>
+
<string name="wifi_p2p_dialog_title">Wi-Fi Direct</string>
<string name="wifi_p2p_turnon_message">Start Wi-Fi Direct. This will turn off Wi-Fi client/hotspot.</string>
<string name="wifi_p2p_failed_message">Couldn\'t start Wi-Fi Direct.</string>
@@ -3643,6 +3828,7 @@
<string name="wifi_p2p_show_pin_message">PIN: </string>
<string name="wifi_p2p_frequency_conflict_message" product="tablet">The tablet will temporarily disconnect from Wi-Fi while it\'s connected to <xliff:g id="device_name">%1$s</xliff:g></string>
+ <string name="wifi_p2p_frequency_conflict_message" product="tv">The TV will temporarily disconnect from Wi-Fi while it\'s connected to <xliff:g id="device_name">%1$s</xliff:g></string>
<string name="wifi_p2p_frequency_conflict_message" product="default">The phone will temporarily disconnect from Wi-Fi while it\'s connected to <xliff:g id="device_name">%1$s</xliff:g></string>
<!-- Name of the dialog that lets the user choose an accented character to insert -->
@@ -4352,6 +4538,10 @@
is connected to a headphone or other wired audio output jack. [CHAR LIMIT=50] -->
<string name="default_audio_route_name" product="tablet">Tablet</string>
+ <!-- Name of the default audio route for tablets when nothing
+ is connected to a headphone or other wired audio output jack. [CHAR LIMIT=50] -->
+ <string name="default_audio_route_name" product="tv">TV</string>
+
<!-- Name of the default audio route when nothing is connected to
a headphone or other wired audio output jack. [CHAR LIMIT=50] -->
<string name="default_audio_route_name" product="default">Phone</string>
@@ -4502,6 +4692,12 @@
the tablet will be reset to factory default and all user data will be lost.
</string>
<!-- Message shown when user is almost at the limit of password attempts where the device will be wiped. -->
+ <string name="kg_failed_attempts_almost_at_wipe" product="tv">
+ You have incorrectly attempted to unlock the TV <xliff:g id="number">%d</xliff:g> times.
+ After <xliff:g id="number">%d</xliff:g> more unsuccessful attempts,
+ the TV will be reset to factory default and all user data will be lost.
+ </string>
+ <!-- Message shown when user is almost at the limit of password attempts where the device will be wiped. -->
<string name="kg_failed_attempts_almost_at_wipe" product="default">
You have incorrectly attempted to unlock the phone <xliff:g id="number">%d</xliff:g> times.
After <xliff:g id="number">%d</xliff:g> more unsuccessful attempts,
@@ -4513,6 +4709,11 @@
The tablet will now be reset to factory default.
</string>
<!-- Message shown in dialog when user has exceeded the maximum attempts and the device will now be wiped -->
+ <string name="kg_failed_attempts_now_wiping" product="tv">
+ You have incorrectly attempted to unlock the TV <xliff:g id="number">%d</xliff:g> times.
+ The TV will now be reset to factory default.
+ </string>
+ <!-- Message shown in dialog when user has exceeded the maximum attempts and the device will now be wiped -->
<string name="kg_failed_attempts_now_wiping" product="default">
You have incorrectly attempted to unlock the phone <xliff:g id="number">%d</xliff:g> times.
The phone will now be reset to factory default.
@@ -4527,6 +4728,14 @@
</string>
<!-- Message shown in dialog when user is almost at the limit where they will be
locked out and may have to enter an alternate username/password to unlock the phone -->
+ <string name="kg_failed_attempts_almost_at_login" product="tv">
+ You have incorrectly drawn your unlock pattern <xliff:g id="number">%d</xliff:g> times.
+ After <xliff:g id="number">%d</xliff:g> more unsuccessful attempts,
+ you will be asked to unlock your TV using an email account.\n\n
+ Try again in <xliff:g id="number">%d</xliff:g> seconds.
+ </string>
+ <!-- Message shown in dialog when user is almost at the limit where they will be
+ locked out and may have to enter an alternate username/password to unlock the phone -->
<string name="kg_failed_attempts_almost_at_login" product="default">
You have incorrectly drawn your unlock pattern <xliff:g id="number">%d</xliff:g> times.
After <xliff:g id="number">%d</xliff:g> more unsuccessful attempts,
diff --git a/core/res/res/values/styles.xml b/core/res/res/values/styles.xml
index dd87139..5a59afe 100644
--- a/core/res/res/values/styles.xml
+++ b/core/res/res/values/styles.xml
@@ -43,6 +43,10 @@
<item name="shadowRadius">2.75</item>
</style>
+ <style name="DialogWindowTitleBackground">
+ <item name="background">@drawable/title_bar</item>
+ </style>
+
<style name="DialogWindowTitle">
<item name="maxLines">1</item>
<item name="scrollHorizontally">true</item>
diff --git a/core/res/res/values/styles_material.xml b/core/res/res/values/styles_material.xml
index cc3ded5..e04d901 100644
--- a/core/res/res/values/styles_material.xml
+++ b/core/res/res/values/styles_material.xml
@@ -1128,6 +1128,15 @@
<item name="textAlignment">viewStart</item>
</style>
+ <style name="DialogWindowTitleBackground.Material">
+ <item name="background">@null</item>
+ <item name="paddingStart">?attr/dialogPreferredPadding</item>
+ <item name="paddingEnd">?attr/dialogPreferredPadding</item>
+ <item name="paddingTop">@dimen/dialog_padding_top_material</item>
+ </style>
+
+ <style name="DialogWindowTitleBackground.Material.Light" />
+
<style name="DialogWindowTitle.Material">
<item name="maxLines">1</item>
<item name="scrollHorizontally">true</item>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 24c24f8..69a244d 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -894,6 +894,9 @@
<java-symbol type="string" name="wifi_available_sign_in" />
<java-symbol type="string" name="network_available_sign_in" />
<java-symbol type="string" name="network_available_sign_in_detailed" />
+ <java-symbol type="string" name="wifi_connect_alert_title" />
+ <java-symbol type="string" name="wifi_connect_alert_message" />
+ <java-symbol type="string" name="wifi_connect_default_application" />
<java-symbol type="string" name="wifi_p2p_dialog_title" />
<java-symbol type="string" name="wifi_p2p_enabled_notification_message" />
<java-symbol type="string" name="wifi_p2p_enabled_notification_title" />
@@ -1576,6 +1579,7 @@
<java-symbol type="bool" name="config_allowTheaterModeWakeFromPowerKey" />
<java-symbol type="bool" name="config_allowTheaterModeWakeFromKey" />
<java-symbol type="bool" name="config_allowTheaterModeWakeFromMotion" />
+ <java-symbol type="bool" name="config_allowTheaterModeWakeFromMotionWhenNotDreaming" />
<java-symbol type="bool" name="config_allowTheaterModeWakeFromLidSwitch" />
<java-symbol type="bool" name="config_allowTheaterModeWakeFromDock" />
<java-symbol type="bool" name="config_allowTheaterModeWakeFromWindowLayout" />
diff --git a/core/res/res/values/themes.xml b/core/res/res/values/themes.xml
index d983440..4ba6c0b 100644
--- a/core/res/res/values/themes.xml
+++ b/core/res/res/values/themes.xml
@@ -210,6 +210,7 @@
<item name="dialogTitleIconsDecorLayout">@layout/dialog_title_icons</item>
<item name="dialogCustomTitleDecorLayout">@layout/dialog_custom_title</item>
<item name="dialogTitleDecorLayout">@layout/dialog_title</item>
+ <item name="dialogPreferredPadding">@dimen/dialog_padding</item>
<!-- AlertDialog attributes -->
<item name="alertDialogTheme">@style/Theme.Dialog.Alert</item>
diff --git a/core/res/res/values/themes_material.xml b/core/res/res/values/themes_material.xml
index 5640fc1..b320ae5 100644
--- a/core/res/res/values/themes_material.xml
+++ b/core/res/res/values/themes_material.xml
@@ -178,6 +178,7 @@
<item name="dialogTitleIconsDecorLayout">@layout/dialog_title_icons_material</item>
<item name="dialogCustomTitleDecorLayout">@layout/dialog_custom_title_material</item>
<item name="dialogTitleDecorLayout">@layout/dialog_title_material</item>
+ <item name="dialogPreferredPadding">@dimen/dialog_padding_material</item>
<!-- AlertDialog attributes -->
<item name="alertDialogTheme">@style/Theme.Material.Dialog.Alert</item>
@@ -529,6 +530,7 @@
<item name="dialogTitleIconsDecorLayout">@layout/dialog_title_icons_material</item>
<item name="dialogCustomTitleDecorLayout">@layout/dialog_custom_title_material</item>
<item name="dialogTitleDecorLayout">@layout/dialog_title_material</item>
+ <item name="dialogPreferredPadding">@dimen/dialog_padding_material</item>
<!-- AlertDialog attributes -->
<item name="alertDialogTheme">@style/Theme.Material.Light.Dialog.Alert</item>
@@ -1001,6 +1003,7 @@
<item name="windowFrame">@null</item>
<item name="windowTitleStyle">@style/DialogWindowTitle.Material</item>
+ <item name="windowTitleBackgroundStyle">@style/DialogWindowTitleBackground.Material</item>
<item name="windowBackground">@drawable/dialog_background_material</item>
<item name="windowElevation">@dimen/floating_window_z</item>
<item name="windowIsFloating">true</item>
@@ -1117,6 +1120,7 @@
<item name="windowFrame">@null</item>
<item name="windowTitleStyle">@style/DialogWindowTitle.Material.Light</item>
+ <item name="windowTitleBackgroundStyle">@style/DialogWindowTitleBackground.Material.Light</item>
<item name="windowBackground">@drawable/dialog_background_material</item>
<item name="windowElevation">@dimen/floating_window_z</item>
<item name="windowIsFloating">true</item>
diff --git a/core/tests/benchmarks/src/android/util/FloatMathBenchmark.java b/core/tests/benchmarks/src/android/util/FloatMathBenchmark.java
new file mode 100644
index 0000000..2858128
--- /dev/null
+++ b/core/tests/benchmarks/src/android/util/FloatMathBenchmark.java
@@ -0,0 +1,116 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.util;
+
+import com.google.caliper.Param;
+import com.google.caliper.Runner;
+import com.google.caliper.SimpleBenchmark;
+
+import android.util.FloatMath;
+
+public class FloatMathBenchmark extends SimpleBenchmark {
+
+ public float timeFloatMathCeil(int reps) {
+ // Keep an answer so we don't optimize the method call away.
+ float f = 0.0f;
+ for (int i = 0; i < reps; i++) {
+ f += FloatMath.ceil(100.123f);
+ }
+ return f;
+ }
+
+ public float timeFloatMathCeil_math(int reps) {
+ // Keep an answer so we don't optimize the method call away.
+ float f = 0.0f;
+ for (int i = 0; i < reps; i++) {
+ f += (float) Math.ceil(100.123f);
+ }
+ return f;
+ }
+
+ public float timeFloatMathCos(int reps) {
+ // Keep an answer so we don't optimize the method call away.
+ float f = 0.0f;
+ for (int i = 0; i < reps; i++) {
+ f += FloatMath.cos(100.123f);
+ }
+ return f;
+ }
+
+ public float timeFloatMathExp(int reps) {
+ // Keep an answer so we don't optimize the method call away.
+ float f = 0.0f;
+ for (int i = 0; i < reps; i++) {
+ f += FloatMath.exp(100.123f);
+ }
+ return f;
+ }
+
+ public float timeFloatMathFloor(int reps) {
+ // Keep an answer so we don't optimize the method call away.
+ float f = 0.0f;
+ for (int i = 0; i < reps; i++) {
+ f += FloatMath.floor(100.123f);
+ }
+ return f;
+ }
+
+ public float timeFloatMathHypot(int reps) {
+ // Keep an answer so we don't optimize the method call away.
+ float f = 0.0f;
+ for (int i = 0; i < reps; i++) {
+ f += FloatMath.hypot(100.123f, 100.123f);
+ }
+ return f;
+ }
+
+ public float timeFloatMathPow(int reps) {
+ // Keep an answer so we don't optimize the method call away.
+ float f = 0.0f;
+ for (int i = 0; i < reps; i++) {
+ f += FloatMath.pow(10.123f, 10.123f);
+ }
+ return f;
+ }
+
+ public float timeFloatMathSin(int reps) {
+ // Keep an answer so we don't optimize the method call away.
+ float f = 0.0f;
+ for (int i = 0; i < reps; i++) {
+ f += FloatMath.sin(100.123f);
+ }
+ return f;
+ }
+
+ public float timeFloatMathSqrt(int reps) {
+ // Keep an answer so we don't optimize the method call away.
+ float f = 0.0f;
+ for (int i = 0; i < reps; i++) {
+ f += FloatMath.sqrt(100.123f);
+ }
+ return f;
+ }
+
+ public float timeFloatMathSqrt_math(int reps) {
+ // Keep an answer so we don't optimize the method call away.
+ float f = 0.0f;
+ for (int i = 0; i < reps; i++) {
+ f += (float) Math.sqrt(100.123f);
+ }
+ return f;
+ }
+
+}
diff --git a/core/tests/coretests/src/android/text/TextUtilsTest.java b/core/tests/coretests/src/android/text/TextUtilsTest.java
index d494c5d..5a6ef30 100644
--- a/core/tests/coretests/src/android/text/TextUtilsTest.java
+++ b/core/tests/coretests/src/android/text/TextUtilsTest.java
@@ -353,6 +353,7 @@
assertNull("null CharSequence should generate null from parcel", text);
p = Parcel.obtain();
TextUtils.writeToParcel("test", p, 0);
+ p.setDataPosition(0);
text = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(p);
assertEquals("conversion to/from parcel failed", "test", text);
}
diff --git a/data/fonts/fallback_fonts.xml b/data/fonts/fallback_fonts.xml
index c4a949f..4b38ad3 100644
--- a/data/fonts/fallback_fonts.xml
+++ b/data/fonts/fallback_fonts.xml
@@ -223,7 +223,28 @@
</family>
<family>
<fileset>
- <file>NotoSansCherokee-Regular.ttf</file>
+ <file>NotoSansThaana-Regular.ttf</file>
+ <file>NotoSansThaana-Bold.ttf</file>
+ </fileset>
+ </family>
+ <family>
+ <fileset>
+ <file>NotoSansBalinese-Regular.ttf</file>
+ </fileset>
+ </family>
+ <family>
+ <fileset>
+ <file>NotoSansBatak-Regular.ttf</file>
+ </fileset>
+ </family>
+ <family>
+ <fileset>
+ <file>NotoSansBuginese-Regular.ttf</file>
+ </fileset>
+ </family>
+ <family>
+ <fileset>
+ <file>NotoSansBuhid-Regular.ttf</file>
</fileset>
</family>
<family>
@@ -233,6 +254,66 @@
</family>
<family>
<fileset>
+ <file>NotoSansCherokee-Regular.ttf</file>
+ </fileset>
+ </family>
+ <family>
+ <fileset>
+ <file>NotoSansHanunoo-Regular.ttf</file>
+ </fileset>
+ </family>
+ <family>
+ <fileset>
+ <file>NotoSansJavanese-Regular.ttf</file>
+ </fileset>
+ </family>
+ <family>
+ <fileset>
+ <file>NotoSansLepcha-Regular.ttf</file>
+ </fileset>
+ </family>
+ <family>
+ <fileset>
+ <file>NotoSansLimbu-Regular.ttf</file>
+ </fileset>
+ </family>
+ <family>
+ <fileset>
+ <file>NotoSansMeeteiMayek-Regular.ttf</file>
+ </fileset>
+ </family>
+ <family>
+ <fileset>
+ <file>NotoSansOlChiki-Regular.ttf</file>
+ </fileset>
+ </family>
+ <family>
+ <fileset>
+ <file>NotoSansRejang-Regular.ttf</file>
+ </fileset>
+ </family>
+ <family>
+ <fileset>
+ <file>NotoSansSaurashtra-Regular.ttf</file>
+ </fileset>
+ </family>
+ <family>
+ <fileset>
+ <file>NotoSansSundanese-Regular.ttf</file>
+ </fileset>
+ </family>
+ <family>
+ <fileset>
+ <file>NotoSansSylotiNagri-Regular.ttf</file>
+ </fileset>
+ </family>
+ <family>
+ <fileset>
+ <file>NotoSansTagbanwa-Regular.ttf</file>
+ </fileset>
+ </family>
+ <family>
+ <fileset>
<file>NotoSansYi-Regular.ttf</file>
</fileset>
</family>
diff --git a/data/fonts/fonts.xml b/data/fonts/fonts.xml
index 09055c6..4493554 100644
--- a/data/fonts/fonts.xml
+++ b/data/fonts/fonts.xml
@@ -220,12 +220,61 @@
<font weight="700" style="normal">NotoSansMyanmarUI-Bold.ttf</font>
</family>
<family>
- <font weight="400" style="normal">NotoSansCherokee-Regular.ttf</font>
+ <font weight="400" style="normal">NotoSansThaana-Regular.ttf</font>
+ <font weight="700" style="normal">NotoSansThaana-Bold.ttf</font>
+ </family>
+ <family>
+ <font weight="400" style="normal">NotoSansBalinese-Regular.ttf</font>
+ </family>
+ <family>
+ <font weight="400" style="normal">NotoSansBatak-Regular.ttf</font>
+ </family>
+ <family>
+ <font weight="400" style="normal">NotoSansBuginese-Regular.ttf</font>
+ </family>
+ <family>
+ <font weight="400" style="normal">NotoSansBuhid-Regular.ttf</font>
</family>
<family>
<font weight="400" style="normal">NotoSansCanadianAboriginal-Regular.ttf</font>
</family>
<family>
+ <font weight="400" style="normal">NotoSansCherokee-Regular.ttf</font>
+ </family>
+ <family>
+ <font weight="400" style="normal">NotoSansHanunoo-Regular.ttf</font>
+ </family>
+ <family>
+ <font weight="400" style="normal">NotoSansJavanese-Regular.ttf</font>
+ </family>
+ <family>
+ <font weight="400" style="normal">NotoSansLepcha-Regular.ttf</font>
+ </family>
+ <family>
+ <font weight="400" style="normal">NotoSansLimbu-Regular.ttf</font>
+ </family>
+ <family>
+ <font weight="400" style="normal">NotoSansMeeteiMayek-Regular.ttf</font>
+ </family>
+ <family>
+ <font weight="400" style="normal">NotoSansOlChiki-Regular.ttf</font>
+ </family>
+ <family>
+ <font weight="400" style="normal">NotoSansRejang-Regular.ttf</font>
+ </family>
+ <family>
+ <font weight="400" style="normal">NotoSansSaurashtra-Regular.ttf</font>
+ </family>
+ <family>
+ <font weight="400" style="normal">NotoSansSundanese-Regular.ttf</font>
+ </family>
+ <family>
+ <font weight="400" style="normal">NotoSansSylotiNagri-Regular.ttf</font>
+ </family>
+ <family>
+ <font weight="400" style="normal">NotoSansTagbanwa-Regular.ttf</font>
+ </family>
+ <family>
<font weight="400" style="normal">NotoSansYi-Regular.ttf</font>
</family>
<family lang="zh-Hans">
diff --git a/docs/html/distribute/tools/promote/device-art-resources/galaxy_nexus/land_back.png b/docs/html/distribute/tools/promote/device-art-resources/galaxy_nexus/land_back.png
deleted file mode 100644
index f340a62..0000000
--- a/docs/html/distribute/tools/promote/device-art-resources/galaxy_nexus/land_back.png
+++ /dev/null
Binary files differ
diff --git a/docs/html/distribute/tools/promote/device-art-resources/galaxy_nexus/land_fore.png b/docs/html/distribute/tools/promote/device-art-resources/galaxy_nexus/land_fore.png
deleted file mode 100644
index 2a4e595..0000000
--- a/docs/html/distribute/tools/promote/device-art-resources/galaxy_nexus/land_fore.png
+++ /dev/null
Binary files differ
diff --git a/docs/html/distribute/tools/promote/device-art-resources/galaxy_nexus/land_shadow.png b/docs/html/distribute/tools/promote/device-art-resources/galaxy_nexus/land_shadow.png
deleted file mode 100644
index f3a3120..0000000
--- a/docs/html/distribute/tools/promote/device-art-resources/galaxy_nexus/land_shadow.png
+++ /dev/null
Binary files differ
diff --git a/docs/html/distribute/tools/promote/device-art-resources/galaxy_nexus/port_back.png b/docs/html/distribute/tools/promote/device-art-resources/galaxy_nexus/port_back.png
deleted file mode 100644
index c40b37c..0000000
--- a/docs/html/distribute/tools/promote/device-art-resources/galaxy_nexus/port_back.png
+++ /dev/null
Binary files differ
diff --git a/docs/html/distribute/tools/promote/device-art-resources/galaxy_nexus/port_fore.png b/docs/html/distribute/tools/promote/device-art-resources/galaxy_nexus/port_fore.png
deleted file mode 100644
index aae684b..0000000
--- a/docs/html/distribute/tools/promote/device-art-resources/galaxy_nexus/port_fore.png
+++ /dev/null
Binary files differ
diff --git a/docs/html/distribute/tools/promote/device-art-resources/galaxy_nexus/port_shadow.png b/docs/html/distribute/tools/promote/device-art-resources/galaxy_nexus/port_shadow.png
deleted file mode 100644
index 61a0da9..0000000
--- a/docs/html/distribute/tools/promote/device-art-resources/galaxy_nexus/port_shadow.png
+++ /dev/null
Binary files differ
diff --git a/docs/html/distribute/tools/promote/device-art-resources/galaxy_nexus/thumb.png b/docs/html/distribute/tools/promote/device-art-resources/galaxy_nexus/thumb.png
deleted file mode 100644
index e21a421..0000000
--- a/docs/html/distribute/tools/promote/device-art-resources/galaxy_nexus/thumb.png
+++ /dev/null
Binary files differ
diff --git a/docs/html/distribute/tools/promote/device-art-resources/nexus_6/land_back.png b/docs/html/distribute/tools/promote/device-art-resources/nexus_6/land_back.png
new file mode 100644
index 0000000..06695f5
--- /dev/null
+++ b/docs/html/distribute/tools/promote/device-art-resources/nexus_6/land_back.png
Binary files differ
diff --git a/docs/html/distribute/tools/promote/device-art-resources/nexus_6/land_fore.png b/docs/html/distribute/tools/promote/device-art-resources/nexus_6/land_fore.png
new file mode 100644
index 0000000..9fe5409
--- /dev/null
+++ b/docs/html/distribute/tools/promote/device-art-resources/nexus_6/land_fore.png
Binary files differ
diff --git a/docs/html/distribute/tools/promote/device-art-resources/nexus_6/land_shadow.png b/docs/html/distribute/tools/promote/device-art-resources/nexus_6/land_shadow.png
new file mode 100644
index 0000000..99f826f
--- /dev/null
+++ b/docs/html/distribute/tools/promote/device-art-resources/nexus_6/land_shadow.png
Binary files differ
diff --git a/docs/html/distribute/tools/promote/device-art-resources/nexus_6/port_back.png b/docs/html/distribute/tools/promote/device-art-resources/nexus_6/port_back.png
new file mode 100644
index 0000000..6e1aec6
--- /dev/null
+++ b/docs/html/distribute/tools/promote/device-art-resources/nexus_6/port_back.png
Binary files differ
diff --git a/docs/html/distribute/tools/promote/device-art-resources/nexus_6/port_fore.png b/docs/html/distribute/tools/promote/device-art-resources/nexus_6/port_fore.png
new file mode 100644
index 0000000..53ec73a
--- /dev/null
+++ b/docs/html/distribute/tools/promote/device-art-resources/nexus_6/port_fore.png
Binary files differ
diff --git a/docs/html/distribute/tools/promote/device-art-resources/nexus_6/port_shadow.png b/docs/html/distribute/tools/promote/device-art-resources/nexus_6/port_shadow.png
new file mode 100644
index 0000000..66149c6
--- /dev/null
+++ b/docs/html/distribute/tools/promote/device-art-resources/nexus_6/port_shadow.png
Binary files differ
diff --git a/docs/html/distribute/tools/promote/device-art-resources/nexus_6/thumb.png b/docs/html/distribute/tools/promote/device-art-resources/nexus_6/thumb.png
new file mode 100644
index 0000000..bc1f492
--- /dev/null
+++ b/docs/html/distribute/tools/promote/device-art-resources/nexus_6/thumb.png
Binary files differ
diff --git a/docs/html/distribute/tools/promote/device-art-resources/nexus_9/land_back.png b/docs/html/distribute/tools/promote/device-art-resources/nexus_9/land_back.png
new file mode 100644
index 0000000..fdbc52c
--- /dev/null
+++ b/docs/html/distribute/tools/promote/device-art-resources/nexus_9/land_back.png
Binary files differ
diff --git a/docs/html/distribute/tools/promote/device-art-resources/nexus_9/land_fore.png b/docs/html/distribute/tools/promote/device-art-resources/nexus_9/land_fore.png
new file mode 100644
index 0000000..76fc78e
--- /dev/null
+++ b/docs/html/distribute/tools/promote/device-art-resources/nexus_9/land_fore.png
Binary files differ
diff --git a/docs/html/distribute/tools/promote/device-art-resources/nexus_9/land_shadow.png b/docs/html/distribute/tools/promote/device-art-resources/nexus_9/land_shadow.png
new file mode 100644
index 0000000..d40758f
--- /dev/null
+++ b/docs/html/distribute/tools/promote/device-art-resources/nexus_9/land_shadow.png
Binary files differ
diff --git a/docs/html/distribute/tools/promote/device-art-resources/nexus_9/port_back.png b/docs/html/distribute/tools/promote/device-art-resources/nexus_9/port_back.png
new file mode 100644
index 0000000..fd6f88f
--- /dev/null
+++ b/docs/html/distribute/tools/promote/device-art-resources/nexus_9/port_back.png
Binary files differ
diff --git a/docs/html/distribute/tools/promote/device-art-resources/nexus_9/port_fore.png b/docs/html/distribute/tools/promote/device-art-resources/nexus_9/port_fore.png
new file mode 100644
index 0000000..328ceef
--- /dev/null
+++ b/docs/html/distribute/tools/promote/device-art-resources/nexus_9/port_fore.png
Binary files differ
diff --git a/docs/html/distribute/tools/promote/device-art-resources/nexus_9/port_shadow.png b/docs/html/distribute/tools/promote/device-art-resources/nexus_9/port_shadow.png
new file mode 100644
index 0000000..13eba2f
--- /dev/null
+++ b/docs/html/distribute/tools/promote/device-art-resources/nexus_9/port_shadow.png
Binary files differ
diff --git a/docs/html/distribute/tools/promote/device-art-resources/nexus_9/thumb.png b/docs/html/distribute/tools/promote/device-art-resources/nexus_9/thumb.png
new file mode 100644
index 0000000..bb52e6c
--- /dev/null
+++ b/docs/html/distribute/tools/promote/device-art-resources/nexus_9/thumb.png
Binary files differ
diff --git a/docs/html/distribute/tools/promote/device-art-resources/nexus_s/land_back.png b/docs/html/distribute/tools/promote/device-art-resources/nexus_s/land_back.png
deleted file mode 100644
index f525e8e..0000000
--- a/docs/html/distribute/tools/promote/device-art-resources/nexus_s/land_back.png
+++ /dev/null
Binary files differ
diff --git a/docs/html/distribute/tools/promote/device-art-resources/nexus_s/land_fore.png b/docs/html/distribute/tools/promote/device-art-resources/nexus_s/land_fore.png
deleted file mode 100644
index e26bfe1..0000000
--- a/docs/html/distribute/tools/promote/device-art-resources/nexus_s/land_fore.png
+++ /dev/null
Binary files differ
diff --git a/docs/html/distribute/tools/promote/device-art-resources/nexus_s/land_shadow.png b/docs/html/distribute/tools/promote/device-art-resources/nexus_s/land_shadow.png
deleted file mode 100644
index ea26b73..0000000
--- a/docs/html/distribute/tools/promote/device-art-resources/nexus_s/land_shadow.png
+++ /dev/null
Binary files differ
diff --git a/docs/html/distribute/tools/promote/device-art-resources/nexus_s/port_back.png b/docs/html/distribute/tools/promote/device-art-resources/nexus_s/port_back.png
deleted file mode 100644
index ed4ad0c..0000000
--- a/docs/html/distribute/tools/promote/device-art-resources/nexus_s/port_back.png
+++ /dev/null
Binary files differ
diff --git a/docs/html/distribute/tools/promote/device-art-resources/nexus_s/port_fore.png b/docs/html/distribute/tools/promote/device-art-resources/nexus_s/port_fore.png
deleted file mode 100644
index 74bd077..0000000
--- a/docs/html/distribute/tools/promote/device-art-resources/nexus_s/port_fore.png
+++ /dev/null
Binary files differ
diff --git a/docs/html/distribute/tools/promote/device-art-resources/nexus_s/port_shadow.png b/docs/html/distribute/tools/promote/device-art-resources/nexus_s/port_shadow.png
deleted file mode 100644
index bb4bec8..0000000
--- a/docs/html/distribute/tools/promote/device-art-resources/nexus_s/port_shadow.png
+++ /dev/null
Binary files differ
diff --git a/docs/html/distribute/tools/promote/device-art-resources/nexus_s/thumb.png b/docs/html/distribute/tools/promote/device-art-resources/nexus_s/thumb.png
deleted file mode 100644
index 8b9a3d9..0000000
--- a/docs/html/distribute/tools/promote/device-art-resources/nexus_s/thumb.png
+++ /dev/null
Binary files differ
diff --git a/docs/html/distribute/tools/promote/device-art-resources/xoom/land_back.png b/docs/html/distribute/tools/promote/device-art-resources/xoom/land_back.png
deleted file mode 100644
index e1eb075..0000000
--- a/docs/html/distribute/tools/promote/device-art-resources/xoom/land_back.png
+++ /dev/null
Binary files differ
diff --git a/docs/html/distribute/tools/promote/device-art-resources/xoom/land_fore.png b/docs/html/distribute/tools/promote/device-art-resources/xoom/land_fore.png
deleted file mode 100644
index 15e5f50..0000000
--- a/docs/html/distribute/tools/promote/device-art-resources/xoom/land_fore.png
+++ /dev/null
Binary files differ
diff --git a/docs/html/distribute/tools/promote/device-art-resources/xoom/land_shadow.png b/docs/html/distribute/tools/promote/device-art-resources/xoom/land_shadow.png
deleted file mode 100644
index 885508a..0000000
--- a/docs/html/distribute/tools/promote/device-art-resources/xoom/land_shadow.png
+++ /dev/null
Binary files differ
diff --git a/docs/html/distribute/tools/promote/device-art-resources/xoom/port_back.png b/docs/html/distribute/tools/promote/device-art-resources/xoom/port_back.png
deleted file mode 100644
index 290ca35..0000000
--- a/docs/html/distribute/tools/promote/device-art-resources/xoom/port_back.png
+++ /dev/null
Binary files differ
diff --git a/docs/html/distribute/tools/promote/device-art-resources/xoom/port_fore.png b/docs/html/distribute/tools/promote/device-art-resources/xoom/port_fore.png
deleted file mode 100644
index 8b3dca3..0000000
--- a/docs/html/distribute/tools/promote/device-art-resources/xoom/port_fore.png
+++ /dev/null
Binary files differ
diff --git a/docs/html/distribute/tools/promote/device-art-resources/xoom/port_shadow.png b/docs/html/distribute/tools/promote/device-art-resources/xoom/port_shadow.png
deleted file mode 100644
index 895b75e..0000000
--- a/docs/html/distribute/tools/promote/device-art-resources/xoom/port_shadow.png
+++ /dev/null
Binary files differ
diff --git a/docs/html/distribute/tools/promote/device-art-resources/xoom/thumb.png b/docs/html/distribute/tools/promote/device-art-resources/xoom/thumb.png
deleted file mode 100644
index 8fd08a4..0000000
--- a/docs/html/distribute/tools/promote/device-art-resources/xoom/thumb.png
+++ /dev/null
Binary files differ
diff --git a/docs/html/distribute/tools/promote/device-art.jd b/docs/html/distribute/tools/promote/device-art.jd
index 1736060..3902b30 100644
--- a/docs/html/distribute/tools/promote/device-art.jd
+++ b/docs/html/distribute/tools/promote/device-art.jd
@@ -66,7 +66,7 @@
}
.device-list {
- padding: 0;
+ padding: 1em 0 0 0;
margin: 0;
}
@@ -187,6 +187,19 @@
portSize: [1080,1920],
},
{
+ id: 'nexus_6',
+ title: 'Nexus 6',
+ url: 'http://www.google.com/nexus/6/',
+ physicalSize: 6,
+ physicalHeight: 6.27,
+ density: '560DPI',
+ landRes: ['shadow', 'back', 'fore'],
+ landOffset: [489,327],
+ portRes: ['shadow', 'back', 'fore'],
+ portOffset: [327,489],
+ portSize: [1440, 2560],
+ },
+ {
id: 'nexus_7',
title: 'Nexus 7',
url: 'http://www.google.com/nexus/7/',
@@ -201,6 +214,20 @@
portSize: [800,1280]
},
{
+ id: 'nexus_9',
+ title: 'Nexus 9',
+ url: 'http://www.google.com/nexus/9/',
+ physicalSize: 9,
+ physicalHeight: 8.98,
+ actualResolution: [1536,2048],
+ density: 'XHDPI',
+ landRes: ['shadow', 'back', 'fore'],
+ landOffset: [514,350],
+ portRes: ['shadow', 'back', 'fore'],
+ portOffset: [348,514],
+ portSize: [1536,2048],
+ },
+ {
id: 'nexus_10',
title: 'Nexus 10',
url: 'http://www.google.com/nexus/10/',
@@ -212,19 +239,6 @@
landOffset: [227,217],
portRes: ['shadow', 'back', 'fore'],
portOffset: [217,223],
- portSize: [800,1280]
- },
- {
- id: 'xoom',
- title: 'Motorola XOOM',
- url: 'http://www.google.com/phone/detail/motorola-xoom',
- physicalSize: 10,
- physicalHeight: 6.61,
- density: 'MDPI',
- landRes: ['shadow', 'back', 'fore'],
- landOffset: [218,191],
- portRes: ['shadow', 'back', 'fore'],
- portOffset: [199,200],
portSize: [800,1280],
archived: true
},
@@ -256,34 +270,6 @@
portSize: [768,1280],
archived: true
},
- {
- id: 'galaxy_nexus',
- title: 'Galaxy Nexus',
- url: 'http://www.android.com/devices/detail/galaxy-nexus',
- physicalSize: 4.65,
- physicalHeight: 5.33,
- density: 'XHDPI',
- landRes: ['shadow', 'back', 'fore'],
- landOffset: [371,199],
- portRes: ['shadow', 'back', 'fore'],
- portOffset: [216,353],
- portSize: [720,1280],
- archived: true
- },
- {
- id: 'nexus_s',
- title: 'Nexus S',
- url: 'http://www.google.com/phone/detail/nexus-s',
- physicalSize: 4.0,
- physicalHeight: 4.88,
- density: 'HDPI',
- landRes: ['shadow', 'back', 'fore'],
- landOffset: [247,135],
- portRes: ['shadow', 'back', 'fore'],
- portOffset: [134,247],
- portSize: [480,800],
- archived: true
- }
];
DEVICES = DEVICES.sort(function(x, y) { return x.physicalSize - y.physicalSize; });
diff --git a/docs/html/guide/appendix/glossary.jd b/docs/html/guide/appendix/glossary.jd
index af60eb7..db518f9 100644
--- a/docs/html/guide/appendix/glossary.jd
+++ b/docs/html/guide/appendix/glossary.jd
@@ -94,7 +94,7 @@
Plugin, DDMS is integrated into your development environment. See <a
href="{@docRoot}tools/debugging/ddms.html">Using DDMS</a> to learn more about the program.</dd>
- <dt id="dialog">Dialog</dt> <dd> A floating window that that acts as a lightweight
+ <dt id="dialog">Dialog</dt> <dd> A floating window that acts as a lightweight
form. A dialog can have button controls only and is intended to perform a
simple action (such as button choice) and perhaps return a value. A dialog
is not intended to persist in the history stack, contain complex layout,
diff --git a/docs/html/guide/faq/commontasks.jd b/docs/html/guide/faq/commontasks.jd
index 086721f..2943aef 100644
--- a/docs/html/guide/faq/commontasks.jd
+++ b/docs/html/guide/faq/commontasks.jd
@@ -653,7 +653,7 @@
<p>You can highlight or style the formatting of strings or substrings of text in
a TextView object. There are two ways to do this:</p>
<ul>
- <li>If you use a <a href="{@docRoot}guide/topics/resources/available-resources.html#stringresources">string resource</a>,
+ <li>If you use a <a href="{@docRoot}guide/topics/resources/string-resource.html">string resource</a>,
you can add some simple styling, such as bold or italic using HTML notation.
The currently supported tags are: <code>B</code> (bold),
<code>I</code> (italic), <code>U</code> (underline),
@@ -661,8 +661,8 @@
<code>SUP</code> (superscript), <code>SUB</code> (subscript),
and <code>STRIKE</code> (strikethrough).
So, for example, in res/values/strings.xml you could declare this:<br />
- <code><resource><br />
- <string id="@+id/styled_welcome_message">We
+ <code><resources><br />
+ <string name="styled_welcome_message">We
are <b><i>so</i></b> glad to see you.</string><br />
</resources></code></li>
<li>To style text on the fly, or to add highlighting or more complex styling,
diff --git a/docs/html/guide/topics/graphics/2d-graphics.jd b/docs/html/guide/topics/graphics/2d-graphics.jd
index 4b5a121..9cae53c 100644
--- a/docs/html/guide/topics/graphics/2d-graphics.jd
+++ b/docs/html/guide/topics/graphics/2d-graphics.jd
@@ -228,9 +228,9 @@
<p>The following code snippet demonstrates how to build an {@link android.widget.ImageView} that
uses an image from drawable resources and add it to the layout.</p>
<pre>
- LinearLayout mLinearLayout;
+LinearLayout mLinearLayout;
- protected void onCreate(Bundle savedInstanceState) {
+protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Create a LinearLayout in which to add the ImageView
@@ -241,20 +241,20 @@
i.setImageResource(R.drawable.my_image);
i.setAdjustViewBounds(true); // set the ImageView bounds to match the Drawable's dimensions
i.setLayoutParams(new Gallery.LayoutParams(LayoutParams.WRAP_CONTENT,
- LayoutParams.WRAP_CONTENT));
+ LayoutParams.WRAP_CONTENT));
// Add the ImageView to the layout and set the layout as the content view
mLinearLayout.addView(i);
setContentView(mLinearLayout);
- }
+}
</pre>
<p>In other cases, you may want to handle your image resource as a
{@link android.graphics.drawable.Drawable} object.
To do so, create a Drawable from the resource like so:
<pre>
- Resources res = mContext.getResources();
- Drawable myImage = res.getDrawable(R.drawable.my_image);
- </pre>
+Resources res = mContext.getResources();
+Drawable myImage = res.getDrawable(R.drawable.my_image);
+</pre>
<p class="warning"><strong>Note:</strong> Each unique resource in your project can maintain only
one state, no matter how many different objects you may instantiate for it. For example, if you
@@ -269,12 +269,12 @@
<p>The XML snippet below shows how to add a resource Drawable to an
{@link android.widget.ImageView} in the XML layout (with some red tint just for fun).
<pre>
- <ImageView
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:tint="#55ff0000"
- android:src="@drawable/my_image"/>
- </pre>
+<ImageView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:tint="#55ff0000"
+ android:src="@drawable/my_image"/>
+</pre>
<p>For more information on using project resources, read about
<a href="{@docRoot}guide/topics/resources/index.html">Resources and Assets</a>.</p>
@@ -305,22 +305,22 @@
<h4 id="drawable-xml-example">Example</h4>
<p>Here's some XML that defines a TransitionDrawable:</p>
<pre>
- <transition xmlns:android="http://schemas.android.com/apk/res/android">
- <item android:drawable="@drawable/image_expand">
- <item android:drawable="@drawable/image_collapse">
- </transition>
- </pre>
+<transition xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:drawable="@drawable/image_expand">
+ <item android:drawable="@drawable/image_collapse">
+</transition>
+</pre>
<p>With this XML saved in the file <code>res/drawable/expand_collapse.xml</code>,
the following code will instantiate the TransitionDrawable and set it as the content of an
ImageView:</p>
<pre>
- Resources res = mContext.getResources();
- TransitionDrawable transition = (TransitionDrawable)
-res.getDrawable(R.drawable.expand_collapse);
- ImageView image = (ImageView) findViewById(R.id.toggle_image);
- image.setImageDrawable(transition);
- </pre>
+Resources res = mContext.getResources();
+TransitionDrawable transition = (TransitionDrawable)
+ res.getDrawable(R.drawable.expand_collapse);
+ImageView image = (ImageView) findViewById(R.id.toggle_image);
+image.setImageDrawable(transition);
+</pre>
<p>Then this transition can be run forward (for 1 second) with:</p>
<pre>transition.startTransition(1000);</pre>
@@ -337,7 +337,7 @@
primitive shapes and style them in any way imaginable.</p>
<p>A ShapeDrawable is an extension of {@link android.graphics.drawable.Drawable}, so you can use
-one where ever
+one wherever
a Drawable is expected — perhaps for the background of a View, set with
{@link android.view.View#setBackgroundDrawable(android.graphics.drawable.Drawable)
setBackgroundDrawable()}.
@@ -349,27 +349,27 @@
Here's a basic extension of the View class that does just this, to draw a ShapeDrawable as a
View:</p>
<pre>
- public class CustomDrawableView extends View {
- private ShapeDrawable mDrawable;
+public class CustomDrawableView extends View {
+ private ShapeDrawable mDrawable;
- public CustomDrawableView(Context context) {
- super(context);
+ public CustomDrawableView(Context context) {
+ super(context);
- int x = 10;
- int y = 10;
- int width = 300;
- int height = 50;
+ int x = 10;
+ int y = 10;
+ int width = 300;
+ int height = 50;
- mDrawable = new ShapeDrawable(new OvalShape());
- mDrawable.getPaint().setColor(0xff74AC23);
- mDrawable.setBounds(x, y, x + width, y + height);
- }
+ mDrawable = new ShapeDrawable(new OvalShape());
+ mDrawable.getPaint().setColor(0xff74AC23);
+ mDrawable.setBounds(x, y, x + width, y + height);
+ }
- protected void onDraw(Canvas canvas) {
- mDrawable.draw(canvas);
- }
- }
- </pre>
+ protected void onDraw(Canvas canvas) {
+ mDrawable.draw(canvas);
+ }
+}
+</pre>
<p>In the constructor, a ShapeDrawable is defines as an {@link
android.graphics.drawable.shapes.OvalShape}.
@@ -379,15 +379,15 @@
<p>With the custom View defined, it can be drawn any way you like. With the sample above, we can
draw the shape programmatically in an Activity:</p>
<pre>
- CustomDrawableView mCustomDrawableView;
+CustomDrawableView mCustomDrawableView;
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- mCustomDrawableView = new CustomDrawableView(this);
+protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ mCustomDrawableView = new CustomDrawableView(this);
- setContentView(mCustomDrawableView);
- }
- </pre>
+ setContentView(mCustomDrawableView);
+}
+</pre>
<p>If you'd like to draw this custom drawable from the XML layout instead of from the Activity,
then the CustomDrawable class must override the {@link
@@ -396,11 +396,11 @@
instantiating a View via inflation from XML. Then add a CustomDrawable element to the XML,
like so:</p>
<pre>
- <com.example.shapedrawable.CustomDrawableView
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- />
- </pre>
+<com.example.shapedrawable.CustomDrawableView
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ />
+</pre>
<p>The ShapeDrawable class (like many other Drawable types in the {@link
android.graphics.drawable} package)
diff --git a/docs/html/guide/topics/manifest/service-element.jd b/docs/html/guide/topics/manifest/service-element.jd
index 2213b72..e26f263 100644
--- a/docs/html/guide/topics/manifest/service-element.jd
+++ b/docs/html/guide/topics/manifest/service-element.jd
@@ -138,7 +138,7 @@
</p></dd>
<dt><a name="prmsn"></a>{@code android:permission}</dt>
-<dd>The name of a permission that that an entity must have in order to
+<dd>The name of a permission that an entity must have in order to
launch the service or bind to it. If a caller of
<code>{@link android.content.Context#startService startService()}</code>,
<code>{@link android.content.Context#bindService bindService()}</code>, or
@@ -156,7 +156,7 @@
<p>
For more information on permissions, see the
-<a href="{@docRoot}guide/topics/manifest/manifest-intro.html#sectperm">Permissions</a>
+<a href="{@docRoot}guide/topics/manifest/manifest-intro.html#perms">Permissions</a>
section in the introduction and a separate document,
<a href="{@docRoot}guide/topics/security/security.html">Security and Permissions</a>.
</p></dd>
diff --git a/docs/html/guide/topics/search/searchable-config.jd b/docs/html/guide/topics/search/searchable-config.jd
index fc13c04..e38024c 100644
--- a/docs/html/guide/topics/search/searchable-config.jd
+++ b/docs/html/guide/topics/search/searchable-config.jd
@@ -329,7 +329,7 @@
<dt><code>android:suggestActionMsg</code></dt>
<dd><em>String</em>. An action message to be sent if the action key is pressed while a
suggestion is in focus. This is added to the
- intent that that the system passes to your searchable activity (using the action
+ intent that the system passes to your searchable activity (using the action
you've defined for the suggestion). To examine the string,
use {@link android.content.Intent#getStringExtra
getStringExtra(SearchManager.ACTION_MSG)}. This should only be used if all your
diff --git a/docs/html/guide/topics/ui/settings.jd b/docs/html/guide/topics/ui/settings.jd
index f454c4e..02f1255 100644
--- a/docs/html/guide/topics/ui/settings.jd
+++ b/docs/html/guide/topics/ui/settings.jd
@@ -801,7 +801,7 @@
<h3 id="Listening">Listening for preference changes</h3>
-<p>There are several reasons you might want to be notified as soon as the use changes one of the
+<p>There are several reasons you might want to be notified as soon as the user changes one of the
preferences. In order to receive a callback when a change happens to any one of the preferences,
implement the {@link android.content.SharedPreferences.OnSharedPreferenceChangeListener
SharedPreference.OnSharedPreferenceChangeListener} interface and register the listener for the
diff --git a/docs/html/images/screens_support/as-mac-avds-config.png b/docs/html/images/screens_support/as-mac-avds-config.png
new file mode 100644
index 0000000..35467ff
--- /dev/null
+++ b/docs/html/images/screens_support/as-mac-avds-config.png
Binary files differ
diff --git a/docs/html/images/tools/as-hide-side.png b/docs/html/images/tools/as-hide-side.png
new file mode 100644
index 0000000..1c602f2
--- /dev/null
+++ b/docs/html/images/tools/as-hide-side.png
Binary files differ
diff --git a/docs/html/images/tools/as-run.png b/docs/html/images/tools/as-run.png
new file mode 100644
index 0000000..76c7020
--- /dev/null
+++ b/docs/html/images/tools/as-run.png
Binary files differ
diff --git a/docs/html/images/training/firstapp/studio-new-activity.png b/docs/html/images/training/firstapp/studio-new-activity.png
new file mode 100644
index 0000000..997d455
--- /dev/null
+++ b/docs/html/images/training/firstapp/studio-new-activity.png
Binary files differ
diff --git a/docs/html/images/training/firstapp/studio-setup-1.png b/docs/html/images/training/firstapp/studio-setup-1.png
new file mode 100644
index 0000000..25b8fd8
--- /dev/null
+++ b/docs/html/images/training/firstapp/studio-setup-1.png
Binary files differ
diff --git a/docs/html/reference/com/google/android/gms/location/LocationRequest.html b/docs/html/reference/com/google/android/gms/location/LocationRequest.html
index 6e73c8a..7c97326 100644
--- a/docs/html/reference/com/google/android/gms/location/LocationRequest.html
+++ b/docs/html/reference/com/google/android/gms/location/LocationRequest.html
@@ -2636,7 +2636,7 @@
<p>This interval is inexact. You may not receive updates at all (if no location sources
are available), or you may receive them slower than requested. You may also receive them
faster than requested (if other applications are requesting location at a faster interval).
- The fastest rate that that you will receive updates can be controlled with
+ The fastest rate that you will receive updates can be controlled with
<code><a href="/reference/com/google/android/gms/location/LocationRequest.html#setFastestInterval(long)">setFastestInterval(long)</a></code>. By default this fastest rate is 6x the interval frequency.
<p>Applications with only the coarse location permission may have their interval silently
diff --git a/docs/html/sdk/index.jd b/docs/html/sdk/index.jd
index a646795..cdbed81 100644
--- a/docs/html/sdk/index.jd
+++ b/docs/html/sdk/index.jd
@@ -2,7 +2,7 @@
page.tags=download
page.template=sdk
header.hide=1
-page.metaDescription=Download the official Android SDK to develop apps for Android-powered devices.
+page.metaDescription=Download the official Android developer tools to develop apps for Android-powered devices.
sdk.version=23.0.2
@@ -57,7 +57,7 @@
-<div style="position:relative;height:660px;">
+<div style="position:relative;height:460px;">
<div class="wrap" id="tos" style="position:absolute;display:none;width:inherit;">
@@ -67,7 +67,7 @@
-<p class="sdk-terms-intro">Before installing the Android SDK, you must agree to the following terms and conditions.</p>
+<p class="sdk-terms-intro">Before installing the Android Studio or the standlone Android SDK, you must agree to the following terms and conditions.</p>
<div class="sdk-terms" onfocus="this.blur()">
<h2 class="norule">Terms and Conditions</h2>
@@ -96,7 +96,7 @@
3.2 You agree that Google or third parties own all legal right, title and interest in and to the SDK, including any Intellectual Property Rights that subsist in the SDK. "Intellectual Property Rights" means any and all rights under patent law, copyright law, trade secret law, trademark law, and any and all other proprietary rights. Google reserves all rights not expressly granted to you.
-3.3 You may not use the SDK for any purpose not expressly permitted by this License Agreement. Except to the extent required by applicable third party licenses, you may not: (a) copy (except for backup purposes), modify, adapt, redistribute, decompile, reverse engineer, disassemble, or create derivative works of the SDK or any part of the SDK; or (b) load any part of the SDK onto a mobile handset or any other hardware device except a personal computer, combine any part of the SDK with other software, or distribute any software or device incorporating a part of the SDK.
+3.3 You may not use the SDK for any purpose not expressly permitted by this License Agreement. Except to the extent required by applicable third party licenses, you may not: (a) copy (except for backup purposes), modify, adapt, redistribute, decompile, reverse engineer, disassemble, or create derivative works of the SDK or any part of the SDK; or (b) load any part of the SDK onto a mobile handset or any other hardware device except a personal computer, combine any part of the SDK with other software, or distribute any software or device incorporating a part of the SDK.
3.4 You agree that you will not take any actions that may cause or result in the fragmentation of Android, including but not limited to distributing, participating in the creation of, or promoting in any way a software development kit derived from the SDK.
@@ -240,70 +240,66 @@
<div class="col-6" style="margin-left:0">
-<h1 style="margin-top:0">Get the Android SDK</h1>
+<h1 style="margin-top:0">Android Developer Tools</h1>
+
<p>The Android SDK provides the API libraries and developer tools necessary to build, test,
- and debug apps for Android.</p>
+and debug apps for Android.</p>
-<p>Download the ADT Bundle to quickly start developing apps. It includes the essential Android
-SDK components and a version of the Eclipse IDE with built-in <b>ADT (Android Developer Tools)</b>
-to streamline your Android app development.</p>
+<p>Android Studio is the new official Android IDE, and with a single download includes everything
+you need to begin developing Android apps:</p>
-
-<!-- this appears when viewing the online docs -->
-<div class="online" style="margin-bottom:85px">
-
-<a class="big button subtitle" id="download-bundle-button"
-href="" style="width:295px;display:block;margin:25px 0" ></a>
-
-<p id="not-supported">Choose the SDK package for your OS from the table below.</p>
-
-
- <p>With a single download, the Eclipse ADT bundle
-includes everything you need to begin developing apps:</p>
<ul>
-<li>Eclipse + ADT plugin</li>
+<li>IntelliJ IDE + Android Studio plugin</li>
<li>Android SDK Tools</li>
<li>Android Platform-tools</li>
<li>A version of the Android platform</li>
<li>A version of the Android system image for the emulator</li>
</ul>
+<a class="big button subtitle" id="download-bundle-button"
+href="" style="width:235px;display:block;margin:25px 0" ></a>
+
+
+<!-- this appears when viewing the online docs -->
+<div class="online" style="margin-bottom:85px">
+
+<p id="not-supported">Choose the SDK package for your OS from the table below.</p>
</div>
<!-- end online -->
-
<!-- this appears when viewing the offline docs -->
<p class="offline">
-To get the ADT Bundle or stand-alone SDK Tools, please visit the web site at <a
-href="http://developer.android.com/sdk/index.html">developer.android.com/sdk/</a>
+To get Android Studio or stand-alone SDK Tools, please visit the web site at <a
+href="http://developer.android.com/download/index.html">developer.android.com/download/</a>
</p>
</div><!-- end col-6 (left column) -->
+<div class="col-7" style="background: #ddd;
+ padding: 20px 20px; width:350px; margin:0px 0 0 0px;">
+
+ <h3 style="margin-top:0"><strong>Android Studio 1.0 has arrived!</strong>
+ </h3>
+
+<p>Android Studio is the new official Android IDE. Click the button on this page to download
+Android Studio. If you are still using Eclipse ADT,
+<a href="{@docRoot}tools/eclipse/migrate-adt.html">consider migrating to Android Studio</a>.</p> </div>
+
+
<div class="col-7" style="margin-right:0;">
- <img src="{@docRoot}images/tools-home.png" alt="" height="347" width="400" />
+ <img src="{@docRoot}images/tools/laptop-studio.png" alt="" height="327" width="370" />
</div><!-- end col-7 -->
-
-
-
-<div class="col-7" style="background: #ddd;
- padding: 30px 20px; width:350px; margin:20px 0 0 20px;">
-
- <h3 style="margin-top:0">
- <a href="/sdk/installing/studio.html">Get Android Studio Beta</a>
- </h3>
-
<p>
Android Studio is a new IDE powered by IntelliJ that provides new features and improvements
- over ADT. It's currently in beta but will be the official Android IDE once it's ready.</p>
+ over ADT. It is the official Android IDE.</p>
<p>
If you're a new Android developer, you should consider starting with Android Studio, because the
ADT plugin for Eclipse is no longer in active development.</p>
@@ -312,16 +308,12 @@
</div>
-
-
<!-- alternative SDK options -->
<div class="col-13" style="margin:-70px 0 0;">
-<p style="width:340px">If you prefer to use an existing version of Eclipse or another IDE,
-you can instead download the stand-alone Android SDK Tools:</p>
-
-
+<p style="width:340px">If you prefer to use another IDE or run the tools from the
+command line or build scripts, you can instead download the stand-alone Android SDK Tools:</p>
<h4 id="ExistingIDE"><a href='' class="expandable"
@@ -330,11 +322,13 @@
<div class="col-13 myide" style="margin:0 0 15px;display:none;">
-<p>If you already have an IDE you want to use for Android app development,
-setting up a new SDK requires that you download the SDK Tools, then
+<p>If you want to use an IDE other than IntelliJ or run Android SDK tools from
+the command line or build scripts,
+setting up a new SDK requires that you download the Android SDK Tools, then
select additional Android SDK packages to install (such as the Android platform
-and system image). If you'll be using an existing version of Eclipse, then you can add
-the ADT plugin to it.</p>
+and system image).
+</p>
+
<p>
<a class="button subtitle" id="download-tools-button" href="" style="display:none" ></a>
</p>
diff --git a/docs/html/sdk/installing/index.jd b/docs/html/sdk/installing/index.jd
index 68f4eb7..1dc268b 100644
--- a/docs/html/sdk/installing/index.jd
+++ b/docs/html/sdk/installing/index.jd
@@ -25,52 +25,6 @@
-<!-- ################### ADT BUNDLE ####################### -->
-<div id="adt" heading="Installing the Eclipse ADT Bundle" style="display:none">
-
-
-<p>The Eclipse ADT Bundle provides everything you need to start developing apps, including
-the Android SDK tools and a version of the Eclipse IDE with built-in ADT
-(Android Developer Tools) to streamline your Android app development.</p>
-
-<p>If you didn't download the Eclipse ADT bundle, go <a href="{@docRoot}sdk/index.html"
-><b>download the Eclipse ADT bundle now</b></a>, or switch to the
-<a href="{@docRoot}sdk/installing/index.html?pkg=studio">Android Studio
-install</a> or <a href="{@docRoot}sdk/installing/index.html?pkg=tools">stand-alone SDK Tools
-install</a> instructions</i>.</p>
-
-<div class="procedure-box">
-<p><b>To set up the ADT Bundle:</b></p>
-<ol>
-<li>Unpack the ZIP file
-(named {@code adt-bundle-<os_platform>.zip}) and save it to an appropriate location,
-such as a "Development" directory in your home directory.</li>
-<li>Open the {@code adt-bundle-<os_platform>/eclipse/} directory and launch
-<strong>Eclipse</strong>.</li>
-</ol>
-
-<p class="caution"><strong>Caution:</strong> Do not move any of the files or directories
-from the {@code adt-bundle-<os_platform>} directory. If you move the {@code eclipse/}
-or {@code sdk/} directory, ADT will not be able to locate the SDK and you'll
-need to manually update the ADT preferences.</p>
-</div>
-
-<p>Eclipse with ADT is now ready and loaded with the Android developer tools, but there are still
-a couple packages you should add to make your Android SDK complete.</p>
-
-<p class="paging-links">
-<a href="{@docRoot}sdk/installing/adding-packages.html" class="next-page-link">
-Continue: Adding SDK Packages</a></p>
-
-
-</div>
-<!-- ################ END ADT BUNDLE ##################### -->
-
-
-
-
-
-
<!-- ################ STUDIO ##################### -->
<div id="studio" heading="Installing Android Studio" style="display:none">
@@ -79,10 +33,7 @@
the Android SDK tools to streamline your Android app development.</p>
<p>If you didn't download Android Studio, go <a href="{@docRoot}sdk/installing/studio.html"
-><b>download Android Studio now</b></a>, or switch to the
-<a href="{@docRoot}sdk/installing/index.html?pkg=adt">Eclipse ADT
-install</a> or <a href="{@docRoot}sdk/installing/index.html?pkg=tools">stand-alone SDK Tools
-install</a> instructions.</p>
+><b>download Android Studio now</b></a>.</p>
<p>Before you set up Android Studio, be sure you have installed
@@ -239,7 +190,7 @@
<p><b>To get started on Mac OSX:</b></p>
<p>Unpack the ZIP file you've downloaded. By default, it's unpacked
-into a directory named <code>android-sdk-mac_x86</code>. Move it to an appropriate location on your
+into a directory named <code>android-sdk-mac_x86</code>. Move it to an appropriate location on your
machine, such as a "Development" directory in your home directory.</p>
<p>Make a note of the name and location of the SDK directory on your system—you will need to
@@ -322,6 +273,52 @@
+<!-- ################### ADT BUNDLE ####################### -->
+<div id="adt" heading="Installing the Eclipse ADT Bundle" style="display:none">
+
+
+<p>The Eclipse ADT Bundle provides everything you need to start developing apps, including
+the Android SDK tools and a version of the Eclipse IDE with built-in ADT
+(Android Developer Tools) to streamline your Android app development.</p>
+
+<p>If you didn't download the Eclipse ADT bundle, go <a href="{@docRoot}sdk/index.html"
+><b>download the Eclipse ADT bundle now</b></a>, or switch to the
+<a href="{@docRoot}sdk/installing/index.html?pkg=studio">Android Studio
+install</a> or <a href="{@docRoot}sdk/installing/index.html?pkg=tools">stand-alone SDK Tools
+install</a> instructions</i>.</p>
+
+<div class="procedure-box">
+<p><b>To set up the ADT Bundle:</b></p>
+<ol>
+<li>Unpack the ZIP file
+(named {@code adt-bundle-<os_platform>.zip}) and save it to an appropriate location,
+such as a "Development" directory in your home directory.</li>
+<li>Open the {@code adt-bundle-<os_platform>/eclipse/} directory and launch
+<strong>Eclipse</strong>.</li>
+</ol>
+
+<p class="caution"><strong>Caution:</strong> Do not move any of the files or directories
+from the {@code adt-bundle-<os_platform>} directory. If you move the {@code eclipse/}
+or {@code sdk/} directory, ADT will not be able to locate the SDK and you'll
+need to manually update the ADT preferences.</p>
+</div>
+
+<p>Eclipse with ADT is now ready and loaded with the Android developer tools, but there are still
+a couple packages you should add to make your Android SDK complete.</p>
+
+<p class="paging-links">
+<a href="{@docRoot}sdk/installing/adding-packages.html" class="next-page-link">
+Continue: Adding SDK Packages</a></p>
+
+
+</div>
+<!-- ################ END ADT BUNDLE ##################### -->
+
+
+
+
+
+
<!-- ################ DEFAULT ##################### -->
@@ -329,16 +326,11 @@
<div id="default" style="display:none">
<p>If you haven't already, <b><a href="{@docRoot}sdk/index.html">download
-the Android SDK</a></b>. </p>
+the Android SDK bundle for Android Studio or the stand-alone SDK Tools</a></b>. </p>
-<p>Then, select which SDK package you want to install:</p>
+<p>Then, select which SDK bundle you want to install:</p>
<div class="cols" style="margin:30px 0 60px">
-<div class="col-4" style="margin-left:0">
-<a href="{@docRoot}sdk/installing/index.html?pkg=adt" class="landing-button landing-secondary">
-Eclipse ADT
-</a>
-</div>
<div class="col-4">
<a href="{@docRoot}sdk/installing/index.html?pkg=studio" class="landing-button landing-secondary">
@@ -353,6 +345,16 @@
</div>
</div>
+<p></p>
+
+<div>
+<p></p>
+<p>If you are still using Eclipse ADT, you can still <a href="{@docRoot}sdk/index.html">download</a>
+and <a href="{@docRoot}sdk/installing/index.html?pkg=adt">install </a> the current release.
+However, <a href="{@docRoot}tools/eclipse/migrate-adt.html">consider migrating to Android Studio</a>
+as the Eclipse ADT plugin is no longer in active development.</p>
+
+</div>
</div>
<!-- ################ END DEFAULT ##################### -->
diff --git a/docs/html/sdk/installing/studio.jd b/docs/html/sdk/installing/studio.jd
index f02cdbc..1bcee0a 100644
--- a/docs/html/sdk/installing/studio.jd
+++ b/docs/html/sdk/installing/studio.jd
@@ -1,7 +1,7 @@
page.title=Android Studio
page.tags="studio"
page.image=images/resource-card-android-studio.png
-page.metaDescription=Learn about the new features in the beta release of our new IDE.
+page.metaDescription=Learn about the new features in Android Studio.
@jd:body
diff --git a/docs/html/tools/debugging/ddms.jd b/docs/html/tools/debugging/ddms.jd
index d2fb47a..1b59875 100644
--- a/docs/html/tools/debugging/ddms.jd
+++ b/docs/html/tools/debugging/ddms.jd
@@ -140,7 +140,7 @@
<li>Click <strong>Get Allocations</strong> to see a list of objects that have been allocated
since you clicked on the <strong>Start Tracking</strong> button. You can click on <strong>Get
- Allocations</strong> again to append to the list new objects that that have been
+ Allocations</strong> again to append to the list new objects that have been
allocated.</li>
<li>To stop tracking or to clear the data and start over, click the <strong>Stop Tracking
diff --git a/docs/html/tools/help/monkey.jd b/docs/html/tools/help/monkey.jd
index b6300a7..941f5d9 100644
--- a/docs/html/tools/help/monkey.jd
+++ b/docs/html/tools/help/monkey.jd
@@ -12,7 +12,7 @@
<a name="overview"></a>
<h2>Overview</h2>
-<p>The Monkey is a command-line tool that that you can run on any emulator
+<p>The Monkey is a command-line tool that you can run on any emulator
instance or on a device. It sends a pseudo-random stream of
user events into the system, which acts as a stress test on the application software you are
developing.</p>
diff --git a/docs/html/tools/revisions/build-tools.jd b/docs/html/tools/revisions/build-tools.jd
index ec88efc..4afdf13 100644
--- a/docs/html/tools/revisions/build-tools.jd
+++ b/docs/html/tools/revisions/build-tools.jd
@@ -77,6 +77,17 @@
<div class="toggle-content opened">
<p><a href="#" onclick="return toggleContent(this)">
<img src="{@docRoot}assets/images/triangle-opened.png" class="toggle-content-img"
+ alt=""/>Build Tools, Revision 21.1.1</a> <em>(November 2014)</em>
+ </p>
+ <div class="toggle-content-toggleme">
+ <p>Fixed multidex script issues.</p>
+ </div>
+</div>
+
+
+<div class="toggle-content closed">
+ <p><a href="#" onclick="return toggleContent(this)">
+ <img src="{@docRoot}assets/images/triangle-closed.png" class="toggle-content-img"
alt=""/>Build Tools, Revision 21.1</a> <em>(October 2014)</em>
</p>
<div class="toggle-content-toggleme">
diff --git a/docs/html/tools/testing/testing_eclipse.jd b/docs/html/tools/testing/testing_eclipse.jd
index 7d3be47..6c9d55b 100644
--- a/docs/html/tools/testing/testing_eclipse.jd
+++ b/docs/html/tools/testing/testing_eclipse.jd
@@ -218,7 +218,7 @@
<p>
Another useful convention is to add the method <code>testPreconditions()</code> to your test
class. Use this method to test that the application under test is initialized correctly. If this
- test fails, you know that that the initial conditions were in error. When this happens, further
+ test fails, you know that the initial conditions were in error. When this happens, further
test results are suspect, regardless of whether or not the tests succeeded.
</p>
<p>
diff --git a/docs/html/tools/testing/testing_otheride.jd b/docs/html/tools/testing/testing_otheride.jd
index 9484158..a774087 100644
--- a/docs/html/tools/testing/testing_otheride.jd
+++ b/docs/html/tools/testing/testing_otheride.jd
@@ -281,7 +281,7 @@
<p>
Another useful convention is to add the method <code>testPreConditions()</code> to your test
class. Use this method to test that the application under test is initialized correctly. If this
- test fails, you know that that the initial conditions were in error. When this happens, further
+ test fails, you know that the initial conditions were in error. When this happens, further
test results are suspect, regardless of whether or not the tests succeeded.
</p>
<p>
diff --git a/docs/html/tools/tools_toc.cs b/docs/html/tools/tools_toc.cs
index ac33185..1d6ce36 100644
--- a/docs/html/tools/tools_toc.cs
+++ b/docs/html/tools/tools_toc.cs
@@ -1,10 +1,12 @@
<ul id="nav">
+
+<!-- Downloads menu-->
+
<li class="nav-section">
- <div class="nav-section-header"><a href="<?cs var:toroot
-?>sdk/index.html"><span class="en">Download</span></a></div>
+ <div class="nav-section-header"><a href="<?cs var:toroot?>sdk/index.html"><span class="en">Download</span></a></div>
<ul>
- <li><a href="<?cs var:toroot ?>sdk/installing/index.html">
+ <li><a href="<?cs var:toroot ?>sdk/installing/index.html">
<span class="en">Installing the SDK</span></a></li>
<li><a href="<?cs var:toroot ?>sdk/installing/adding-packages.html">
@@ -13,27 +15,17 @@
</li>
- <li class="nav-section">
- <div class="nav-section-header">
- <a href="<?cs var:toroot ?>sdk/installing/studio.html">Android Studio</a>
- </div>
- <ul>
- <li><a href="<?cs var:toroot ?>sdk/installing/migrate.html">
- Migrating from Eclipse</a></li>
- <li><a href="<?cs var:toroot ?>sdk/installing/create-project.html">
- Creating a Project</a></li>
- <li><a href="<?cs var:toroot ?>sdk/installing/studio-tips.html">
- Tips and Tricks</a></li>
- <li><a href="<?cs var:toroot ?>sdk/installing/studio-androidview.html">
- Using the Android Project View</a></li>
- <li><a href="<?cs var:toroot ?>sdk/installing/studio-layout.html">
- Using the Layout Editor</a></li>
- <li><a href="<?cs var:toroot ?>sdk/installing/studio-build.html">
- Building Your Project with Gradle</a></li>
- <li><a href="<?cs var:toroot ?>sdk/installing/studio-debug.html">
- Debugging with Android Studio</a></li>
- </ul>
- </li>
+<!-- Android Studio Basics menu-->
+
+ <li class="nav-section">
+ <div class="nav-section-header empty">
+ <a href="<?cs var:toroot ?>tools/studio/index.html">Android Studio Basics</a>
+ </div>
+ </li><!-- End of Android Studio Basics -->
+
+
+
+<!-- Workflow menu-->
<li class="nav-section">
<div class="nav-section-header">
@@ -58,7 +50,7 @@
<li class="nav-section">
<div class="nav-section-header"><a href="<?cs var:toroot ?>tools/projects/index.html"><span class="en">Setting Up Projects</span></a></div>
<ul>
- <li><a href="<?cs var:toroot ?>tools/projects/projects-eclipse.html"><span class="en">From Eclipse with ADT</span></a></li>
+ <li><a href="<?cs var:toroot ?>tools/projects/projects-studio.html"><span class="en">From Android Studio</span></a></li>
<li><a href="<?cs var:toroot ?>tools/projects/projects-cmdline.html"><span class="en">From the Command Line</span></a></li>
<li><a href="<?cs var:toroot ?>tools/projects/templates.html"><span class="en">Using Code Templates</span></a></li>
</ul>
@@ -78,7 +70,6 @@
<li><a href="<?cs var:toroot ?>tools/building/multidex.html">
<span class="en">Apps Over 65K Methods</span></a></li>
</ul>
- </li>
<li class="nav-section">
@@ -90,8 +81,8 @@
<a href="<?cs var:toroot?>tools/testing/testing_android.html">
<span class="en">Fundamentals</span></a>
</li>
- <li><a href="<?cs var:toroot ?>tools/testing/testing_eclipse.html">
- <span class="en">From Eclipse</span></a>
+ <li><a href="<?cs var:toroot ?>tools/testing/testing_studio.html">
+ <span class="en">From Android Studio</span></a>
</li>
<li><a href="<?cs var:toroot ?>tools/testing/testing_otheride.html">
<span class="en">From Other IDEs</span></a>
@@ -130,7 +121,7 @@
<li class="nav-section">
<div class="nav-section-header"><a href="<?cs var:toroot ?>tools/debugging/index.html"><span class="en">Debugging</span></a></div>
<ul>
- <li><a href="<?cs var:toroot ?>tools/debugging/debugging-projects.html"><span class="en">From Eclipse with ADT</span></a></li>
+ <li><a href="<?cs var:toroot ?>tools/debugging/debugging-studio.html"><span class="en">From Android Studio</span></a></li>
<li><a href="<?cs var:toroot ?>tools/debugging/debugging-projects-cmdline.html"><span class="en">From Other IDEs</span></a></li>
<li><a href="<?cs var:toroot ?>tools/debugging/ddms.html"><span class="en">Using DDMS</span></a></li>
<li><a href="<?cs var:toroot ?>tools/debugging/debugging-log.html"><span class="en">Reading and Writing Logs</span></a></li>
@@ -151,29 +142,17 @@
</ul>
</li>
</ul>
- </li>
+ </li><!-- end of debugging -->
+
+
+
+<!-- Tool Help menu-->
<li class="nav-section">
- <div class="nav-section-header"><a href="<?cs var:toroot ?>tools/support-library/index.html"><span
-class="en">Support Library</span></a></div>
- <ul>
- <li><a href="<?cs var:toroot ?>tools/support-library/features.html">Features</a></li>
- <li><a href="<?cs var:toroot ?>tools/support-library/setup.html">Setup</a></li>
- </ul>
- </li>
-
- <li class="nav-section">
- <div class="nav-section-header"><a href="<?cs var:toroot ?>tools/help/index.html"><span
-class="en">Tools Help</span></a></div>
+ <div class="nav-section-header"><a href="<?cs var:toroot ?>tools/help/index.html"><span class="en">Tools Help</span></a></div>
<ul>
<li><a href="<?cs var:toroot ?>tools/help/adb.html">adb</a></li>
- <li class="nav-section">
- <div class="nav-section-header"><a href="<?cs var:toroot ?>tools/help/adt.html">ADT</a></div>
- <ul>
- <li><a href="<?cs var:toroot ?>sdk/installing/installing-adt.html">
- <span class="en">Installing the Eclipse Plugin</span></a></li>
- </ul>
- </li>
+ <li><a href="<?cs var:toroot ?>tools/help/adt.html">ADT</a></li>
<li><a href="<?cs var:toroot ?>tools/help/android.html">android</a></li>
<li><a href="<?cs var:toroot ?>tools/help/avd-manager.html">AVD Manager</a></li>
<li><a href="<?cs var:toroot ?>tools/help/bmgr.html">bmgr</a>
@@ -190,15 +169,12 @@
<li><a href="<?cs var:toroot ?>tools/help/mksdcard.html">mksdcard</a></li>
<li><a href="<?cs var:toroot ?>tools/help/monkey.html">monkey</a></li>
<li class="nav-section">
- <div class="nav-section-header"><a href="<?cs var:toroot
-?>tools/help/monkeyrunner_concepts.html"><span class="en">monkeyrunner</span></a></div>
+ <div class="nav-section-header"><a href="<?cs var:toroot?>tools/help/monkeyrunner_concepts.html">
+<span class="en">monkeyrunner</span></a></div>
<ul>
- <li><a href="<?cs var:toroot ?>tools/help/MonkeyDevice.html"><span
-class="en">MonkeyDevice</span></a></li>
- <li><a href="<?cs var:toroot ?>tools/help/MonkeyImage.html"><span
-class="en">MonkeyImage</span></a></li>
- <li><a href="<?cs var:toroot ?>tools/help/MonkeyRunner.html"><span
-class="en">MonkeyRunner</span></a></li>
+ <li><a href="<?cs var:toroot ?>tools/help/MonkeyDevice.html"><span class="en">MonkeyDevice</span></a></li>
+ <li><a href="<?cs var:toroot ?>tools/help/MonkeyImage.html"><span class="en">MonkeyImage</span></a></li>
+ <li><a href="<?cs var:toroot ?>tools/help/MonkeyRunner.html"><span class="en">MonkeyRunner</span></a></li>
</ul>
</li>
<li><a href="<?cs var:toroot ?>tools/help/proguard.html">ProGuard</a></li>
@@ -207,7 +183,8 @@
<li><a href="<?cs var:toroot ?>tools/help/gltracer.html">Tracer for OpenGL ES</a></li>
<li><a href="<?cs var:toroot ?>tools/help/traceview.html">Traceview</a></li>
<li class="nav-section">
- <div class="nav-section-header"><a href="<?cs var:toroot ?>tools/help/uiautomator/index.html"><span class="en">uiautomator</span></a></div>
+ <div class="nav-section-header"><a href="<?cs var:toroot ?>tools/help/uiautomator/index.html">
+<span class="en">uiautomator</span></a></div>
<ul>
<li><a href="<?cs var:toroot ?>tools/help/uiautomator/Configurator.html"><span class="en">Configurator</span></a></li>
<li><a href="<?cs var:toroot ?>tools/help/uiautomator/IAutomationSupport.html"><span class="en">IAutomationSupport</span></a></li>
@@ -224,30 +201,73 @@
<li><a href="<?cs var:toroot ?>tools/help/zipalign.html">zipalign</a></li>
</ul>
</li>
+ </li><!-- end of tools help -->
+
+
+<!-- Build System menu-->
+
+ <li class="nav-section">
+ <div class="nav-section-header">
+ <a href="<?cs var:toroot ?>tools/gradle/index.html">Build System</a>
+ </div>
+ <ul>
+ <li><a href="<?cs var:toroot ?>tools/gradle/studio-build.html">
+ Building Your Project with Gradle</a></li>
+ <li><a href="<?cs var:toroot ?>tools/gradle/gradle-ref.html">
+ Gradle for Android Reference</a></li>
+ </ul>
+ </li><!-- end of build system -->
+
+
+<!-- Support Library menu-->
+
+ <li class="nav-section">
+ <div class="nav-section-header"><a href="<?cs var:toroot ?>tools/support-library/index.html"><span
+class="en">Support Library</span></a></div>
+ <ul>
+ <li><a href="<?cs var:toroot ?>tools/support-library/features.html">Features</a></li>
+ <li><a href="<?cs var:toroot ?>tools/support-library/setup.html">Setup</a></li>
+ </ul>
+ </li><!-- end of support library -->
+
+
+
+<!-- Revision menu-->
<li class="nav-section">
<div class="nav-section-header"><a href="<?cs var:toroot
?>tools/revisions/index.html"><span class="en">Revisions</span></a></div>
<ul>
- <li><a href="<?cs var:toroot ?>tools/sdk/tools-notes.html">
+ <li><a href="<?cs var:toroot ?>tools/revisions/studio-tools.html">
+ <span class="en">Android Studio</span>
+ </a></li>
+ <li><a href="<?cs var:toroot ?>tools/revisions/sdk/tools-notes.html">
<span class="en">SDK Tools</span>
</a></li>
- <li><a href="<?cs var:toroot ?>tools/sdk/eclipse-adt.html">
- <span class="en">ADT Plugin</span>
</a></li>
<li><a href="<?cs var:toroot ?>tools/revisions/build-tools.html">
<span class="en">Build Tools</span>
</a></li>
<li><a href="<?cs var:toroot ?>tools/revisions/platforms.html"><span
class="en">Platforms</span></a></li>
+ <li><a href="<?cs var:toroot ?>tools/revisions/eclipse-adt.html">
+ <span class="en">ADT Plugin</span></a></li>
</ul>
- </li>
+ </li><!-- end of revision -->
+
+
+
+<!-- NDK menu-->
<li class="nav-section">
<div class="nav-section-header empty">
- <a href="<?cs var:toroot ?>tools/sdk/ndk/index.html">NDK</a>
+ <a href="<?cs var:toroot ?>tools/ndk/index.html">NDK</a>
</div>
- </li>
+ </li><!-- end of NDK -->
+
+
+
+<!-- ADK menu-->
<li class="nav-section">
<div class="nav-section-header">
@@ -258,7 +278,26 @@
<li><a href="<?cs var:toroot ?>tools/adk/adk2.html">ADK 2012 Guide</a></li>
<li><a href="<?cs var:toroot ?>tools/adk/adk.html">ADK 2011 Guide</a></li>
</ul>
- </li>
+ </li><!-- end of ADK -->
+
+
+
+<!-- Eclipse ADT menu-->
+
+ <li class="nav-section">
+ <div class="nav-section-header">
+ <a href="<?cs var:toroot ?>tools/eclipse/index.html">
+ <span class="en">Eclipse ADT</span></a>
+ </div>
+ <ul>
+ <li><a href="<?cs var:toroot ?>tools/eclipse/migrate-adt.html">Migrating to Android Studio</a></li>
+ <li><a href="<?cs var:toroot ?>tools/projects/projects-eclipse.html">Projects From Eclipse with ADT</a></li>
+ <li><a href="<?cs var:toroot ?>tools/building/building-eclipse.html">Building From Eclipse with ADT</a></li>
+ <li><a href="<?cs var:toroot ?>tools/debugging/debugging-projects.html">Debugging From Eclipse with ADT</a></li>
+ <li><a href="<?cs var:toroot ?>tools/testing/testing_eclipse.html">Testing From Eclipse</a></li>
+ </ul>
+ </li><!-- end of Eclipse -->
+
</ul><!-- nav -->
diff --git a/docs/html/training/basics/firstapp/building-ui.jd b/docs/html/training/basics/firstapp/building-ui.jd
index 0430cdd..dcf3a16 100644
--- a/docs/html/training/basics/firstapp/building-ui.jd
+++ b/docs/html/training/basics/firstapp/building-ui.jd
@@ -8,9 +8,9 @@
<!-- This is the training bar -->
-<div id="tb-wrapper">
-<div id="tb">
-
+<div id="tb-wrapper">
+<div id="tb">
+
<h2>This lesson teaches you to</h2>
<ol>
@@ -27,16 +27,18 @@
<li><a href="{@docRoot}guide/topics/ui/declaring-layout.html">Layouts</a></li>
</ul>
-</div>
-</div>
+</div>
+</div>
-
+<p>In this lesson, you create a layout in XML that includes a text field and a
+button. In the next lesson, your app responds when the button is pressed by sending the
+content of the text field to another activity.</p>
<p>The graphical user interface for an Android app is built using a hierarchy of {@link
android.view.View} and {@link android.view.ViewGroup} objects. {@link android.view.View} objects are
usually UI widgets such as <a href="{@docRoot}guide/topics/ui/controls/button.html">buttons</a> or
-<a href="{@docRoot}guide/topics/ui/controls/text.html">text fields</a> and {@link
-android.view.ViewGroup} objects are
+<a href="{@docRoot}guide/topics/ui/controls/text.html">text fields</a>.
+{@link android.view.ViewGroup} objects are
invisible view containers that define how the child views are laid out, such as in a
grid or a vertical list.</p>
@@ -44,6 +46,8 @@
android.view.View} and {@link android.view.ViewGroup} so you can define your UI in XML using
a hierarchy of UI elements.</p>
+<p>Layouts are subclasses of the {@link android.view.ViewGroup}. In this exercise, you'll work with
+a {@link android.widget.LinearLayout}.</p>
<div class="sidebox-wrapper">
<div class="sidebox">
@@ -63,33 +67,32 @@
android.view.ViewGroup} objects form branches in the layout and contain other {@link
android.view.View} objects.</p>
-<p>In this lesson, you'll create a layout in XML that includes a text field and a
-button. In the following lesson, you'll respond when the button is pressed by sending the
-content of the text field to another activity.</p>
-
-
<h2 id="LinearLayout">Create a Linear Layout</h2>
-<p>Open the <code>fragment_main.xml</code> file from the <code>res/layout/</code>
-directory.</p>
-
-<p class="note"><strong>Note:</strong> In Eclipse, when you open a layout file, you’re first shown
-the Graphical Layout editor. This is an editor that helps you build layouts using WYSIWYG tools. For this
-lesson, you’re going to work directly with the XML, so click the <em>fragment_main.xml</em> tab at
-the bottom of the screen to open the XML editor.</p>
-
+<ol>
+<li>In Android Studio, from the <code>res/layout</code> directory, open the <code>activity_my.xml</code>
+file.
<p>The BlankActivity template you chose when you created this project includes the
-<code>fragment_main.xml</code> file with a {@link
-android.widget.RelativeLayout} root view and a {@link android.widget.TextView} child view.</p>
+<code>activity_my.xml</code> file with a {@link android.widget.RelativeLayout} root view and a
+{@link android.widget.TextView} child view.</p>
+</li>
+<li>In the <strong>Preview</strong> pane, click the Hide icon <img src="{@docRoot}images/tools/as-hide-side.png"
+ style="vertical-align:baseline;margin:0; max-height:1.5em" /> to close the Preview pane.
+ <p> In Android Studio, when you open a layout file, you’re first shown
+ the Preview pane. Clicking elements in this pane opens the WYSIWYG tools in the Design pane. For
+ this lesson, you’re going to work directly with the XML.</p></li>
+<li>Delete the {@link android.widget.TextView <TextView>} element.</li>
+<li>Change the {@link android.widget.RelativeLayout <RelativeLayout>} element to
+{@link android.widget.LinearLayout <LinearLayout>}.</li>
+<li>Add the <a href="{@docRoot}reference/android/widget/LinearLayout.html#attr_android:orientation">
+{@code android:orientation}</a> attribute and set it to <code>"horizontal"</code>.</li>
+<li>Remove the {@code android:padding} attributes and the {@code tools:context} attribute.
+</ol>
-<p>First, delete the {@link android.widget.TextView <TextView>} element and change the {@link
- android.widget.RelativeLayout <RelativeLayout>} element to {@link
- android.widget.LinearLayout <LinearLayout>}. Then add the
-<a href="{@docRoot}reference/android/widget/LinearLayout.html#attr_android:orientation">{@code
-android:orientation}</a> attribute and set it to <code>"horizontal"</code>.
-The result looks like this:</p>
+</p>The result looks like this:</p>
+<p class="code-caption">res/layout/activity_my.xml</p>
<pre>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
@@ -104,9 +107,9 @@
as specified by the <a
href="{@docRoot}reference/android/widget/LinearLayout.html#attr_android:orientation">{@code
android:orientation}</a> attribute. Each child of a {@link android.widget.LinearLayout} appears on
-the screen in the order in which it appears in the XML.</p>
+the screen in the order in which it appears in the XML.</p>
-<p>The other two attributes, <a
+<p>Two other attributes, <a
href="{@docRoot}reference/android/view/View.html#attr_android:layout_width">{@code
android:layout_width}</a> and <a
href="{@docRoot}reference/android/view/View.html#attr_android:layout_height">{@code
@@ -122,45 +125,32 @@
href="{@docRoot}guide/topics/ui/declaring-layout.html">Layout</a> guide.</p>
-
<h2 id="TextInput">Add a Text Field</h2>
-<p>To create a user-editable text field, add an {@link android.widget.EditText
-<EditText>} element inside the {@link android.widget.LinearLayout <LinearLayout>}.</p>
+<p>As with every {@link android.view.View} object, you must define certain XML attributes to specify
+the {@link android.widget.EditText} object's properties.</p>
-<p>Like every {@link android.view.View} object, you must define certain XML attributes to specify
-the {@link android.widget.EditText} object's properties. Here’s how you should declare it
-inside the {@link android.widget.LinearLayout <LinearLayout>} element:</p>
+<ol>
+<li>In the <code>activity_my.xml</code> file, within the
+{@link android.widget.LinearLayout <LinearLayout>} element, define an
+{@link android.widget.EditText <EditText>} element with the <code>id</code> attribute
+set to <code>@+id/edit_message</code>.</li>
+<li>Define the <code>layout_width</code> and <code>layout_height</code> attributes as
+<code>wrap_content</code>.</li>
+<li>Define a <code>hint</code> attribute as a string object named <code>edit_message</code>.</li>
+</ol>
+<p>The {@link android.widget.EditText <EditText>} element should read as follows:</p>
+
+<p class="code-caption">res/layout/activity_my.xml</p>
<pre>
- <EditText android:id="@+id/edit_message"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:hint="@string/edit_message" />
+<EditText android:id="@+id/edit_message"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:hint="@string/edit_message" />
</pre>
-
-<div class="sidebox-wrapper">
-<div class="sidebox">
- <h3>About resource objects</h3>
- <p>A resource object is simply a unique integer name that's associated with an app resource,
-such as a bitmap, layout file, or string.</p>
- <p>Every resource has a
-corresponding resource object defined in your project's {@code gen/R.java} file. You can use the
-object names in the {@code R} class to refer to your resources, such as when you need to specify a
-string value for the <a
-href="{@docRoot}reference/android/widget/TextView.html#attr_android:hint">{@code android:hint}</a>
-attribute. You can also create arbitrary resource IDs that you associate with a view using the <a
-href="{@docRoot}reference/android/view/View.html#attr_android:id">{@code android:id}</a> attribute,
-which allows you to reference that view from other code.</p>
- <p>The SDK tools generate the {@code R.java} each time you compile your app. You should never
-modify this file by hand.</p>
- <p>For more information, read the guide to <a
-href="{@docRoot}guide/topics/resources/providing-resources.html">Providing Resources</a>.</p>
-</div>
-</div>
-
-<p>About these attributes:</p>
+<p>Here are the {@link android.widget.EditText <EditText>} attributes you added:</p>
<dl>
<dt><a href="{@docRoot}reference/android/view/View.html#attr_android:id">{@code android:id}</a></dt>
@@ -172,11 +162,31 @@
XML. It is followed by the resource type ({@code id} in this case), a slash, then the resource name
({@code edit_message}).</p>
+<div class="sidebox-wrapper">
+<div class="sidebox">
+ <h3>Resource Objects</h3>
+ <p>A resource object is a unique integer name that's associated with an app resource,
+such as a bitmap, layout file, or string.</p>
+ <p>Every resource has a
+corresponding resource object defined in your project's {@code gen/R.java} file. You can use the
+object names in the {@code R} class to refer to your resources, such as when you need to specify a
+string value for the <a
+href="{@docRoot}reference/android/widget/TextView.html#attr_android:hint">{@code android:hint}</a>
+attribute. You can also create arbitrary resource IDs that you associate with a view using the <a
+href="{@docRoot}reference/android/view/View.html#attr_android:id">{@code android:id}</a> attribute,
+which allows you to reference that view from other code.</p>
+ <p>The SDK tools generate the {@code R.java} file each time you compile your app. You should never
+modify this file by hand.</p>
+ <p>For more information, read the guide to <a
+href="{@docRoot}guide/topics/resources/providing-resources.html">Providing Resources</a>.</p>
+</div>
+</div>
+
<p>The plus sign (<code>+</code>) before the resource type is needed only when you're defining a
resource ID for the first time. When you compile the app,
the SDK tools use the ID name to create a new resource ID in
your project's {@code gen/R.java} file that refers to the {@link
-android.widget.EditText} element. Once the resource ID is declared once this way,
+android.widget.EditText} element. With the resource ID declared once this way,
other references to the ID do not
need the plus sign. Using the plus sign is necessary only when specifying a new resource ID and not
needed for concrete resources such as strings or layouts. See the sidebox for
@@ -209,26 +219,25 @@
</dd>
</dl>
-
-
<h2 id="Strings">Add String Resources</h2>
-<p>When you need to add text in the user interface, you should always specify each string as
-a resource. String resources allow you to manage all UI text in a single location,
-which makes it easier to find and update text. Externalizing the strings also allows you to
-localize your app to different languages by providing alternative definitions for each
-string resource.</p>
-
<p>By default, your Android project includes a string resource file at
-<code>res/values/strings.xml</code>. Add a new string named
-<code>"edit_message"</code> and set the value to "Enter a message." (You can delete
-the "hello_world" string.)</p>
+<code>res/values/strings.xml</code>. Here, you'll add a new string named
+<code>"edit_message"</code> and set the value to "Enter a message."</p>
-<p>While you’re in this file, also add a "Send" string for the button you’ll soon add, called
-<code>"button_send"</code>.</p>
+<ol>
+<li>In Android Studio, from the <code>res/values</code> directory, open <code>strings.xml</code>.</li>
+<li>Add a line for a string named <code>"edit_message"</code> with the value, "Enter a message".
+</li>
+<li>Add a line for a string named <code>"button_send"</code> with the value, "Send".
+<p>You'll create the button that uses this string in the next section.</p>
+</li>
+<li>Remove the line for the <code>"hello world"</code> string.</li>
+</ol>
<p>The result for <code>strings.xml</code> looks like this:</p>
+<p class="code-caption">res/values/strings.xml</p>
<pre>
<?xml version="1.0" encoding="utf-8"?>
<resources>
@@ -240,35 +249,59 @@
</resources>
</pre>
+<p>For text in the user interface, always specify each string as
+a resource. String resources allow you to manage all UI text in a single location,
+which makes the text easier to find and update. Externalizing the strings also allows you to
+localize your app to different languages by providing alternative definitions for each
+string resource.</p>
+
<p>For more information about using string resources to localize your app for other languages,
see the <a
href="{@docRoot}training/basics/supporting-devices/index.html">Supporting Different Devices</a>
class.</p>
-
-
<h2 id="Button">Add a Button</h2>
-<p>Now add a {@link android.widget.Button <Button>} to the layout, immediately following the
-{@link android.widget.EditText <EditText>} element:</p>
+<ol>
+<li>In Android Studio, from the <code>res/layout</code> directory, edit the <code>activity_my.xml</code>
+file.</li>
+<li>Within the
+{@link android.widget.LinearLayout <LinearLayout>} element, define a
+{@link android.widget.Button <Button>} element immediately following the
+{@link android.widget.EditText <EditText>} element.</li>
+<li>Set the button's width and height attributes to <code>"wrap_content"</code> so
+the button is only as big as necessary to fit the button's text label.</li>
+<li>Define the button's text label with the <a
+href="{@docRoot}reference/android/widget/TextView.html#attr_android:text">{@code
+android:text}</a> attribute; set its value to the <code>button_send</code> string
+resource you defined in the previous section.</li>
+</ol>
+<p>Your {@link android.widget.LinearLayout <LinearLayout>} should look like this:</p>
+
+<p class="code-caption">res/layout/activity_my.xml</p>
<pre>
- <Button
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="horizontal" >
+ <EditText android:id="@+id/edit_message"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:text="@string/button_send" />
+ android:hint="@string/edit_message" />
+ <Button
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/button_send" />
+</LinearLayout>
</pre>
-<p>The height and width are set to <code>"wrap_content"</code> so the button is only as big as
-necessary to fit the button's text. This button doesn't need the
+<p class="note"><strong>Note:</strong> This button doesn't need the
<a href="{@docRoot}reference/android/view/View.html#attr_android:id">{@code android:id}</a>
attribute, because it won't be referenced from the activity code.</p>
-
-
-<h2 id="Weight">Make the Input Box Fill in the Screen Width</h2>
-
<p>The layout is currently designed so that both the {@link android.widget.EditText} and {@link
android.widget.Button} widgets are only as big as necessary to fit their content, as shown in
figure 2.</p>
@@ -279,7 +312,7 @@
<code>"wrap_content"</code>.</p>
<p>This works fine for the button, but not as well for the text field, because the user might type
-something longer. So, it would be nice to fill the unused screen width
+something longer. It would be nice to fill the unused screen width
with the text field. You can do this inside a
{@link android.widget.LinearLayout} with the <em>weight</em> property, which
you can specify using the <a
@@ -288,9 +321,9 @@
<p>The weight value is a number that specifies the amount of remaining space each view should
consume,
-relative to the amount consumed by sibling views. This works kind of like the
+relative to the amount consumed by sibling views. This works kind of like the
amount of ingredients in a drink recipe: "2
-parts vodka, 1 part coffee liqueur" means two-thirds of the drink is vodka. For example, if you give
+parts soda, 1 part syrup" means two-thirds of the drink is soda. For example, if you give
one view a weight of 2 and another one a weight of 1, the sum is 3, so the first view fills 2/3 of
the remaining space and the second view fills the rest. If you add a third view and give it a weight
of 1, then the first view (with weight of 2) now gets 1/2 the remaining space, while the remaining
@@ -298,38 +331,49 @@
<p>The default weight for all views is 0, so if you specify any weight value
greater than 0 to only one view, then that view fills whatever space remains after all views are
-given the space they require. So, to fill the remaining space in your layout with the {@link
-android.widget.EditText} element, give it a weight of 1 and leave the button with no weight.</p>
+given the space they require.</p>
+<h2 id="Weight">Make the Input Box Fill in the Screen Width</h2>
+
+<p>To fill the remaining space in your layout with the {@link android.widget.EditText} element, do
+the following:</p>
+
+<ol>
+<li>In the <code>activity_my.xml</code> file, assign the
+{@link android.widget.EditText <EditText>} element's <code>layout_weight</code> attribute a value
+of <code>1</code>.</li>
+<li>Also, assign {@link android.widget.EditText <EditText>} element's <code>layout_width</code>
+attribute a value of <code>0dp</code>.
+
+<p class="code-caption">res/layout/activity_my.xml</p>
<pre>
- <EditText
- android:layout_weight="1"
- ... />
+<EditText
+ android:layout_weight="1"
+ android:layout_width="0dp"
+ ... />
</pre>
-<p>In order to improve the layout efficiency when you specify the weight, you should change the
+<p>To improve the layout efficiency when you specify the weight, you should change the
width of the {@link android.widget.EditText} to be
zero (0dp). Setting the width to zero improves layout performance because using
<code>"wrap_content"</code> as the width requires the system to calculate a width that is
ultimately irrelevant because the weight value requires another width calculation to fill the
remaining space.</p>
-<pre>
- <EditText
- android:layout_weight="1"
- android:layout_width="0dp"
- ... />
-</pre>
<p>Figure 3
shows the result when you assign all weight to the {@link android.widget.EditText} element.</p>
<img src="{@docRoot}images/training/firstapp/edittext_gravity.png" />
<p class="img-caption"><strong>Figure 3.</strong> The {@link android.widget.EditText} widget is
-given all the layout weight, so fills the remaining space in the {@link
+given all the layout weight, so it fills the remaining space in the {@link
android.widget.LinearLayout}.</p>
-<p>Here’s how your complete layout file should now look:</p>
+</li>
+</ol>
+<p>Here’s how your complete <code>activity_my.xml</code>layout file should now look:</p>
+
+<p class="code-caption">res/layout/activity_my.xml</p>
<pre>
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
@@ -349,13 +393,16 @@
</LinearLayout>
</pre>
+<h2>Run Your App</h2>
+
<p>This layout is applied by the default {@link android.app.Activity} class
-that the SDK tools generated when you created the project, so you can now run the app to see the
+that the SDK tools generated when you created the project. Run the app to see the
results:</p>
<ul>
- <li>In Eclipse, click Run <img src="{@docRoot}images/tools/eclipse-run.png"
- style="vertical-align:baseline;margin:0" /> from the toolbar.</li>
+ <li>In Android Studio, from the toolbar, click <strong>Run</strong>
+ <img src="{@docRoot}images/tools/as-run.png"
+ style="vertical-align:baseline;margin:0; max-height:1em" />.</li>
<li>Or from a command line, change directories to the root of your Android project and
execute:
<pre>
@@ -364,7 +411,8 @@
</pre></li>
</ul>
-<p>Continue to the next lesson to learn how you can respond to button presses, read content
+<p>Continue to the <a href="starting-activity.html">next
+lesson</a> to learn how to respond to button presses, read content
from the text field, start another activity, and more.</p>
diff --git a/docs/html/training/basics/firstapp/creating-project.jd b/docs/html/training/basics/firstapp/creating-project.jd
index 2e06103..71b93c0 100644
--- a/docs/html/training/basics/firstapp/creating-project.jd
+++ b/docs/html/training/basics/firstapp/creating-project.jd
@@ -17,7 +17,7 @@
<h2>This lesson teaches you to</h2>
<ol>
- <li><a href="#Eclipse">Create a Project with Eclipse</a></li>
+ <li><a href="#Studio">Create a Project with Android Studio</a></li>
<li><a href="#CommandLine">Create a Project with Command Line Tools</a></li>
</ol>
@@ -38,97 +38,145 @@
default project directories and files.</p>
<p>This lesson
-shows how to create a new project either using Eclipse (with the ADT plugin) or using the
+shows how to create a new project either using Android Studio or using the
SDK tools from a command line.</p>
<p class="note"><strong>Note:</strong> You should already have the Android SDK installed, and if
-you're using Eclipse, you should also have the <a href="{@docRoot}tools/sdk/eclipse-adt.html">ADT
-plugin</a> installed (version 22.6.2 or higher). If you don't have these, follow the guide to <a
+you're using Android Studio, you should also have <a href="{@docRoot}sdk/installing/studio.html">
+Android Studio</a> installed. If you don't have these, follow the guide to <a
href="{@docRoot}sdk/installing/index.html">Installing the Android SDK</a> before you start this
lesson.</p>
-<h2 id="Eclipse">Create a Project with Eclipse</h2>
+<h2 id="Studio">Create a Project with Android Studio</h2>
<ol>
- <li>Click <strong>New</strong> <img src="{@docRoot}images/tools/eclipse-new.png"
- style="vertical-align:baseline;margin:0" /> in the toolbar.</li>
- <li>In the window that appears, open the <strong>Android</strong> folder,
- select <strong>Android Application Project</strong>, and click <strong>Next</strong>.</li>
-
-<div class="figure" style="width:420px">
-<img src="{@docRoot}images/training/firstapp/adt-firstapp-setup.png" alt="" />
-<p class="img-caption"><strong>Figure 1.</strong> The New Android App Project wizard in Eclipse.</p>
-</div>
-
- <li>Fill in the form that appears:
+ <li>In Android Studio, create a new project:
+ <ul>
+ <li>If you don't have a project opened, in the <strong>Welcome</strong> screen, click <strong>
+ New Project</strong>.</li>
+ <li>If you have a project opened, from the <strong>File</strong> menu, select <strong>New
+ Project</strong>.</li>
+ </ul>
+ </li>
+ <div class="figure" style="width:420px">
+ <img src="{@docRoot}images/training/firstapp/studio-setup-1.png" alt="" />
+ <p class="img-caption"><strong>Figure 1.</strong> Configuring a new project in Android Studio.</p>
+ </div>
+ <li>Under <strong>Configure your new project</strong>, fill in the fields as shown in figure 1
+ and click <strong>Next</strong>.
+ <p>It will probably be easier to follow these lessons if you use the same values as shown.</p>
<ul>
<li><strong>Application Name</strong> is the app name that appears to users.
- For this project, use "My First App."</p></li>
- <li><strong>Project Name</strong> is the name of your project directory and the name visible in Eclipse.</li>
- <li><strong>Package Name</strong> is the package namespace for your app (following the same
-rules as packages in the Java programming language). Your package name
-must be unique across all packages installed on the Android system. For this reason, it's generally
-best if you use a name that begins with the reverse domain name of your organization or
-publisher entity. For this project, you can use something like "com.example.myfirstapp."
-However, you cannot publish your app on Google Play using the "com.example" namespace.</li>
- <li><strong>Minimum Required SDK</strong> is the lowest version of Android that your app supports,
- indicated using the <a href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#ApiLevels"
- >API level</a>.
- To support as many devices as possible, you should set this to the lowest version available
- that allows your app to provide its core feature set. If any feature of your app is possible
- only on newer versions of Android and it's not critical to the app's core feature set, you
- can enable the feature only when running on the versions that support it (as
- discussed in <a href="{@docRoot}training/basics/supporting-devices/platforms.html"
- >Supporting Different Platform Versions</a>).
- Leave this set to the default value for this project.
- </li>
- <li><strong>Target SDK</strong> indicates the highest version of Android (also using the
- <a href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#ApiLevels"
- >API level</a>) with which you
- have tested with your application.
- <p>As new versions of Android become available, you should
- test your app on the new version and update this value to match the latest API level
- in order to take advantage of new platform features.</p>
- </li>
- <li><strong>Compile With</strong> is the platform version against which you will compile your app.
- By default, this is set to the latest version of Android available in your SDK. (It should
- be Android 4.1 or greater; if you don't have such a version available, you must install one
- using the <a href="{@docRoot}sdk/installing/adding-packages.html">SDK Manager</a>).
- You can still build your app to
-support older versions, but setting the build target to the latest version allows you to
-enable new features and optimize your app for a great user experience on the latest
-devices.</li>
- <li><strong>Theme</strong> specifies the Android UI style to apply for your app. You can leave
- this alone.</li>
+ For this project, use "My First App."</li>
+ <li><strong>Company domain</strong> provides a qualifier that will be appended to the package
+ name; Android Studio will remember this qualifier for each new project you create.</li>
+ <li><strong>Package name</strong> is the fully qualified name for the project (following the
+ same rules as those for naming packages in the Java programming language). Your package name
+ must be unique across all packages installed on the Android system. You can <strong>
+ Edit</strong> this value independently from the application name or the company
+ domain.</li>
+ <li><strong>Project location</strong> is the directory on your system that holds the project
+ files.</li>
</ul>
- <p>Click <strong>Next</strong>.</p>
</li>
- <li>On the next screen to configure the project, leave the default selections and click
- <strong>Next</strong>.</li>
- <li>The next screen can help you create a launcher icon for your app.
- <p>You can customize an icon in several ways and the tool generates an icon for all
- screen densities. Before you publish your app, you should be sure your icon meets
- the specifications defined in the <a
- href="{@docRoot}design/style/iconography.html">Iconography</a>
- design guide.</p>
- <p>Click <strong>Next</strong>.</p>
- </li>
- <li>Now you can select an activity template from which to begin building your app.
- <p>For this project, select <strong>BlankActivity</strong> and click <strong>Next</strong>.</p>
- </li>
- <li>Leave all the details for the activity in their default state and click
- <strong>Finish</strong>.</li>
+ <li>Under <strong>Select the form factors your app will run on</strong>, check the box for <strong>
+ Phone and Tablet</strong>.</li>
+ <li>For <strong>Minimum SDK</strong>, select <strong>API 8: Android 2.2 (Froyo)</strong>.
+ <p>The Minimum Required SDK is the earliest version of Android that your app supports,
+ indicated using the <a href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#ApiLevels">
+ API level</a>. To support as many devices as possible, you should set this to the lowest
+ version available that allows your app to provide its core feature set. If any feature of your
+ app is possible only on newer versions of Android and it's not critical to the app's core
+ feature set, you can enable the feature only when running on the versions that support it (as
+ discussed in <a href="{@docRoot}training/basics/supporting-devices/platforms.html">
+ Supporting Different Platform Versions</a>).</p></li>
+ <li>Leave all of the other options (TV, Wear, and Glass) unchecked and click <strong>Next.</strong></li>
+ <div class="sidebox-wrapper">
+ <div class="sidebox">
+ <h3>Activities</h3>
+ <p>An activity is one of the distinguishing features of the Android framework. Activities
+ provide the user with access to your app, and there may be many activities. An application
+ will usually have a main activity for when the user launches the application, another
+ activity for when she selects some content to view, for example, and other activities for
+ when she performs other tasks within the app. See <a href="{@docRoot}guide/components/activities.html">
+ Activities</a> for more information.</p>
+ </div>
+ </div>
+ <li>Under <strong>Add an activity to your project</strong>, select <strong>Blank Activity</strong>
+ and click <strong>Next</strong>.</li>
+ <li>Under <strong>Describe the new activity for your project</strong>, leave the fields as they
+ are and click <strong>Finish</strong>.</li>
</ol>
-<p>Your Android project is now a basic "Hello World" app that contains some default files.
-To run the app, continue to the <a href="running-app.html">next lesson</a>.</p>
+<p>Your Android project is now a basic "Hello World" app that contains some default files. Take a
+moment to review the most important of these:</p>
+<dl>
+ <dt><code>app/src/main/res/layout/activity_my.xml</code></dt>
+ <dd>This is the XML layout file for the activity you added when you created the project with Android
+ Studio. Following the New Project workflow, Android Studio presents this file with both a text
+ view and a preview of the screen UI. The file includes some default settings and a <code>TextView</code>
+ element that displays the message, "Hello world!"</dd>
+ <dt><code>app/src/main/java/com.mycompany.myfirstapp/MyActivity.java</code></dt>
+ <dd>A tab for this file appears in Android Studio when the New Project workflow finishes. When you
+ select the file you see the class definition for the activity you created. When you build and
+ run the app, the {@link android.app.Activity} class starts the activity and loads the layout file
+ that says "Hello World!"</dd>
+ <dt><code>app/src/res/AndroidManifest.xml</code></dt>
+ <dd>The <a href="{@docRoot}guide/topics/manifest/manifest-intro.html">manifest file</a> describes
+ the fundamental characteristics of the app and defines each of its components. You'll revisit
+ this file as you follow these lessons and add more components to your app.</dd>
+ <dt><code>app/build.gradle</code></dt>
+ <dd>Android Studio uses Gradle to compile and build your app. There is a <code>build.gradle</code>
+ file for each module of your project, as well as a <code>build.gradle</code> file for the entire
+ project. Usually, you're only interested in the <code>build.gradle</code> file for the module,
+ in this case the <code>app</code> or application module. This is where your app's build dependencies
+ are set, including the <code>defaultConfig</code> settings:
+ <ul>
+ <li><code>compiledSdkVersion</code> is the platform version against which you will compile
+ your app. By default, this is set to the latest version of Android available in your SDK.
+ (It should be Android 4.1 or greater; if you don't have such a version available, you must
+ install one using the <a href="{@docRoot}sdk/installing/adding-packages.html">SDK Manager</a>.)
+ You can still build your app to support older versions, but setting this to the latest
+ version allows you to enable new features and optimize your app for a great user experience
+ on the latest devices.</li>
+ <li><code>applicationId</code> is the fully qualified package name for your application that
+ you specified during the New Project workflow.</li>
+ <li><code>minSdkVersion</code> is the Minimum SDK version you specified during the New Project
+ workflow. This is the earliest version of the Android SDK that your app supports.</li>
+ <li><code>targetSdkVersion</code> indicates the highest version of Android with which you have
+ tested your application. As new versions of Android become available, you should
+ test your app on the new version and update this value to match the latest API level and
+ thereby take advantage of new platform features. For more information, read
+ <a href="{@docRoot}training/basics/supporting-devices/platforms.html">Supporting Different
+ Platform Versions</a>.</li>
+ </ul>
+ <p>See <a href="{@docRoot}sdk/installing/studio-build.html">Building Your Project with Gradle</a>
+ for more information about Gradle.</p></dd>
+</dl>
+<p>Note also the <code>/res</code> subdirectories that contain the
+<a href="{@docRoot}guide/topics/resources/overview.html">resources</a> for your application:</p>
+<dl>
+ <dt><code>drawable-hdpi/</code></dt>
+ <dd>Directory for drawable objects (such as bitmaps) that are designed for high-density
+ (hdpi) screens. Other drawable directories contain assets designed for other screen densities.
+ Here you'll find the ic_launcher.png that appears when you run the default app.</dd>
+ <dt><code>layout/</code></dt>
+ <dd>Directory for files that define your app's user interface like activity_my.xml,
+ discussed above, which describes a basic layout for the MyActivity class.</dd>
+ <dt><code>values/</code></dt>
+ <dd>Directory for other XML files that contain a collection of resources, such as
+ string and color definitions. The strings.xml file defines the "Hello world!" string that
+ displays when you run the default app.</dd>
+</dl>
+
+<p>To run the app, continue to the <a href="running-app.html">next lesson</a>.</p>
<h2 id="CommandLine">Create a Project with Command Line Tools</h2>
-<p>If you're not using the Eclipse IDE with the ADT plugin, you can instead create your project
+<p>If you're not using the Android Studio IDE, you can instead create your project
using the SDK tools from a command line:</p>
<ol>
@@ -136,32 +184,32 @@
<li>Execute:
<pre class="no-pretty-print">android list targets</pre>
<p>This prints a list of the available Android platforms that you’ve downloaded for your SDK. Find
-the platform against which you want to compile your app. Make a note of the target id. We
+the platform against which you want to compile your app. Make a note of the target ID. We
recommend that you select the highest version possible. You can still build your app to
support older versions, but setting the build target to the latest version allows you to optimize
your app for the latest devices.</p>
<p>If you don't see any targets listed, you need to
install some using the Android SDK
-Manager tool. See <a href="{@docRoot}sdk/installing/adding-packages.html">Adding Platforms
- and Packages</a>.</p></li>
+Manager tool. See <a href="{@docRoot}sdk/installing/adding-packages.html">Adding SDK
+ Packages</a>.</p></li>
<li>Execute:
<pre class="no-pretty-print">
android create project --target <target-id> --name MyFirstApp \
---path <path-to-workspace>/MyFirstApp --activity MainActivity \
+--path <path-to-workspace>/MyFirstApp --activity MyActivity \
--package com.example.myfirstapp
</pre>
-<p>Replace <code><target-id></code> with an id from the list of targets (from the previous step)
+<p>Replace <code><target-id></code> with an ID from the list of targets (from the previous step)
and replace
<code><path-to-workspace></code> with the location in which you want to save your Android
projects.</p></li>
</ol>
-<p>Your Android project is now a basic "Hello World" app that contains some default files.
-To run the app, continue to the <a href="running-app.html">next lesson</a>.</p>
-
<p class="note"><strong>Tip:</strong> Add the <code>platform-tools/</code> as well as the
<code>tools/</code> directory to your <code>PATH</code> environment variable.</p>
+<p>Your Android project is now a basic "Hello World" app that contains some default files.
+To run the app, continue to the <a href="running-app.html">next lesson</a>.</p>
+
diff --git a/docs/html/training/basics/firstapp/index.jd b/docs/html/training/basics/firstapp/index.jd
index ac8e64a..d5df0b7 100644
--- a/docs/html/training/basics/firstapp/index.jd
+++ b/docs/html/training/basics/firstapp/index.jd
@@ -15,9 +15,8 @@
<h2>Dependencies and prerequisites</h2>
<ul>
- <li><a href="http://developer.android.com/sdk/index.html">Android SDK</a></li>
- <li><a href="{@docRoot}tools/sdk/eclipse-adt.html">ADT Plugin</a> 22.6.2 or higher
- (if you're using Eclipse)</li>
+ <li><a href="{@docRoot}sdk/index.html">Android SDK</a></li>
+ <li><a href="{@docRoot}sdk/installing/studio.html">Android Studio</a></li>
</ul>
</div>
@@ -29,16 +28,19 @@
project and run a debuggable version of the app. You'll also learn some fundamentals of Android app
design, including how to build a simple user interface and handle user input.</p>
+<h2>Set Up Your Environment</h2>
+
<p>Before you start this class, be sure you have your development environment set up. You need
to:</p>
<ol>
- <li>Download the Android SDK.</li>
- <li>Install the ADT plugin for Eclipse (if you’ll use the Eclipse IDE).</li>
- <li>Download the latest SDK tools and platforms using the SDK Manager.</li>
+ <li>Download the <a href="{@docRoot}sdk/index.html">Android SDK</a>.</li>
+ <li>Install <a href="{@docRoot}sdk/installing/studio.html">Android Studio</a>.</li>
+ <li>Download the latest SDK tools and platforms using the <a href="{@docRoot}tools/help/sdk-manager.html">
+ SDK Manager</a>.</li>
</ol>
-<p class="note"><strong>Note:</strong> Make sure you install the most recent versions of the ADT
-plugin and the Android SDK before you start this class. The procedures described in this class may
+<p class="note"><strong>Note:</strong> Make sure you install the most recent versions of Android
+Studio and the Android SDK before you start this class. The procedures described in this class may
not apply to earlier versions.</p>
<p>If you haven't already done these tasks, start by downloading the
diff --git a/docs/html/training/basics/firstapp/running-app.jd b/docs/html/training/basics/firstapp/running-app.jd
index 96b7172..50b4fea 100644
--- a/docs/html/training/basics/firstapp/running-app.jd
+++ b/docs/html/training/basics/firstapp/running-app.jd
@@ -11,9 +11,9 @@
<!-- This is the training bar -->
-<div id="tb-wrapper">
-<div id="tb">
-
+<div id="tb-wrapper">
+<div id="tb">
+
<h2>This lesson teaches you to</h2>
<ol>
@@ -28,85 +28,32 @@
<li><a href="{@docRoot}tools/devices/index.html">Managing Virtual Devices</a></li>
<li><a href="{@docRoot}tools/projects/index.html">Managing Projects</a></li>
</ul>
-
-
-</div>
-</div>
+
+
+</div>
+</div>
<p>If you followed the <a href="creating-project.html">previous lesson</a> to create an
Android project, it includes a default set of "Hello World" source files that allow you to
immediately run the app.</p>
-<p>How you run your app depends on two things: whether you have a real Android-powered device and
-whether you're using Eclipse. This lesson shows you how to install and run your app on a
-real device and on the Android emulator, and in both cases with either Eclipse or the command line
-tools.</p>
-
-<p>Before you run your app, you should be aware of a few directories and files in the Android
-project:</p>
-
-<dl>
- <dt><code>AndroidManifest.xml</code></dt>
- <dd>The <a href="{@docRoot}guide/topics/manifest/manifest-intro.html">manifest file</a> describes
-the fundamental characteristics of the app and defines each of
-its components. You'll learn about various declarations in this file as you read more training
-classes.
- <p>One of the most important elements your manifest should include is the <a
-href="{@docRoot}guide/topics/manifest/uses-sdk-element.html">{@code <uses-sdk>}</a>
-element. This declares your app's compatibility with different Android versions using the <a
-href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#min">{@code android:minSdkVersion}</a>
-and <a
-href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#target">{@code android:targetSdkVersion}</a>
-attributes. For your first app, it should look like this:</p>
-<pre>
-<manifest xmlns:android="http://schemas.android.com/apk/res/android" ... >
- <uses-sdk android:minSdkVersion="8" android:targetSdkVersion="19" />
- ...
-</manifest>
-</pre>
-<p>You should always set the <a
-href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#target">{@code android:targetSdkVersion}</a>
-as high as possible and test your app on the corresponding platform version. For more information,
-read <a href="{@docRoot}training/basics/supporting-devices/platforms.html">Supporting Different
-Platform Versions</a>.</p>
-
- </dd>
- <dt><code>src/</code></dt>
- <dd>Directory for your app's main source files. By default, it includes an {@link
-android.app.Activity} class that runs when your app is launched using the app icon.</dd>
- <dt><code>res/</code></dt>
- <dd>Contains several sub-directories for <a
-href="{@docRoot}guide/topics/resources/overview.html">app resources</a>. Here are just a few:
- <dl style="margin-top:1em">
- <dt><code>drawable-hdpi/</code></dt>
- <dd>Directory for drawable objects (such as bitmaps) that are designed for high-density
-(hdpi) screens. Other drawable directories contain assets designed for other screen densities.</dd>
- <dt><code>layout/</code></dt>
- <dd>Directory for files that define your app's user interface.</dd>
- <dt><code>values/</code></dt>
- <dd>Directory for other various XML files that contain a collection of resources, such as
-string and color definitions.</dd>
- </dl>
- </dd>
-</dl>
-
-<p>When you build and run the default Android app, the default {@link android.app.Activity}
-class starts and loads a layout file
-that says "Hello World." The result is nothing exciting, but it's
-important that you understand how to run your app before you start developing.</p>
-
-
+<p>How you run your app depends on two things: whether you have a real device running Android and
+whether you're using Android Studio. This lesson shows you how to install and run your app on a
+real device and on the Android emulator, and in both cases with either Android Studio or the command
+line tools.</p>
<h2 id="RealDevice">Run on a Real Device</h2>
-<p>If you have a real Android-powered device, here's how you can install and run your app:</p>
+<p>If you have a device running Android, here's how to install and run your app.</p>
+
+<h3>Set up your device</h3>
<ol>
<li>Plug in your device to your development machine with a USB cable.
-If you're developing on Windows, you might need to install the appropriate USB driver for your
-device. For help installing drivers, see the <a href="{@docRoot}tools/extras/oem-usb.html">OEM USB
-Drivers</a> document.</li>
+ If you're developing on Windows, you might need to install the appropriate USB driver for your
+ device. For help installing drivers, see the <a href="{@docRoot}tools/extras/oem-usb.html">OEM
+ USB Drivers</a> document.</li>
<li>Enable <strong>USB debugging</strong> on your device.
<ul>
<li>On most devices running Android 3.2 or older, you can find the option under
@@ -121,19 +68,20 @@
</li>
</ol>
-<p>To run the app from Eclipse:</p>
+<h3>Run the app from Android Studio</h3>
<ol>
<li>Open one of your project's files and click
<strong>Run</strong> <img
-src="{@docRoot}images/tools/eclipse-run.png" style="vertical-align:baseline;margin:0" />
+src="{@docRoot}images/tools/as-run.png" style="vertical-align:baseline;margin:0; max-height:1em" />
from the toolbar.</li>
- <li>In the <strong>Run as</strong> window that appears, select
- <strong>Android Application</strong> and click <strong>OK</strong>.</li>
+ <li>In the <strong>Choose Device</strong> window that appears, select the
+ <strong>Choose a running device</strong> radio button, select your device, and click <strong>OK
+ </strong>.</li>
</ol>
-<p>Eclipse installs the app on your connected device and starts it.</p>
+<p>Android Studio installs the app on your connected device and starts it.</p>
-<p>Or to run your app from a command line:</p>
+<h3>Run the app from a command line</h3>
<ol>
<li>Change directories to the root of your Android project and execute:
@@ -141,7 +89,7 @@
<li>Make sure the Android SDK <code>platform-tools/</code> directory is included in your
<code>PATH</code> environment variable, then execute:
<pre class="no-pretty-print">adb install bin/MyFirstApp-debug.apk</pre></li>
- <li>On your device, locate <em>MyFirstActivity</em> and open it.</li>
+ <li>On your device, locate <em>MyFirstApp</em> and open it.</li>
</ol>
<p>That's how you build and run your Android app on a device!
@@ -152,64 +100,67 @@
<h2 id="Emulator">Run on the Emulator</h2>
-<p>Whether you're using Eclipse or the command line, to run your app on the emulator you need to
-first create an <a href="{@docRoot}tools/devices/index.html">Android Virtual Device</a> (AVD). An
-AVD is a device configuration for the Android emulator that allows you to model different
-devices.</p>
+<p>Whether you're using Android Studio or the command line, to run your app on the emulator you need
+to first create an <a href="{@docRoot}tools/devices/index.html">Android Virtual Device</a> (AVD). An
+AVD is a device configuration for the Android emulator that allows you to model a specific
+device.</p>
<div class="figure" style="width:457px">
- <img src="{@docRoot}images/screens_support/avds-config.png" alt="" />
- <p class="img-caption"><strong>Figure 1.</strong> The AVD Manager showing a few virtual
-devices.</p>
+ <img src="{@docRoot}images/screens_support/as-mac-avds-config.png" />
+ <p class="img-caption"><strong>Figure 1.</strong> The AVD Manager showing a virtual device.</p>
</div>
-<p>To create an AVD:</p>
+<h3>Create an AVD</h3>
<ol>
<li>Launch the Android Virtual Device Manager:
- <ol type="a">
- <li>In Eclipse, click Android Virtual Device Manager
- <img src="{@docRoot}images/tools/avd_manager.png"
-style="vertical-align:baseline;margin:0" /> from the toolbar.</li>
- <li>From the command line, change
-directories to <code><sdk>/tools/</code> and execute:
-<pre class="no-pretty-print">android avd</pre></li>
- </ol>
+ <ul>
+ <li>In the Android Studio tool bar, click the Android Virtual Device Manager icon
+ <img src="{@docRoot}images/tools/avd-manager-studio.png"
+ style="vertical-align:baseline;margin:0; max-height:1em" />.</li>
+ <li>From the command line, change directories to <code><sdk>/tools/</code> and execute:
+ <pre class="no-pretty-print">android avd</pre></li>
+ </ul>
</li>
- <li>In the <em>Android Virtual Device Manager</em> panel, click <strong>New</strong>.</li>
- <li>Fill in the details for the AVD.
-Give it a name, a platform target, an SD card size, and a skin (HVGA is default).</li>
- <li>Click <strong>Create AVD</strong>.</li>
- <li>Select the new AVD from the <em>Android Virtual Device Manager</em> and click
-<strong>Start</strong>.</li>
- <li>After the emulator boots up, unlock the emulator screen.</li>
+ <li>In the <strong>Android Virtual Device Manager</strong> window, click <strong>Create</strong>.</li>
+ <li>Enter an <strong>AVD Name</strong>.</li>
+ <li>Select a <strong>Device</strong> type.
+ <p>When you select a device type, most of the fields auto-populate.</p>
+ <li>For <strong>Skin</strong> select <strong>HVGA</strong>.</li>
+ <li>For <strong>SD Card</strong>, enter something small, like 10 MiB.
+ <p>It really doesn't matter what you enter here since you're not using any storage. But if you
+ reuse this AVD, you might have to adjust this setting.</p></li>
+ <li>Ignore the <strong>Emulation Options</strong> and click <strong>OK</strong>.</li>
+ <li>In the <strong>Result</strong> screen, click <strong>OK</strong>.</li>
+ <li>Close the <strong>Android Virtual Device Manager</strong> window.</li>
</ol>
-<p>To run the app from Eclipse:</p>
+<h3>Run the app from Android Studio</h3>
<ol>
- <li>Open one of your project's files and click
-<strong>Run</strong> <img
-src="{@docRoot}images/tools/eclipse-run.png" style="vertical-align:baseline;margin:0" />
-from the toolbar.</li>
- <li>In the <strong>Run as</strong> window that appears, select
- <strong>Android Application</strong> and click <strong>OK</strong>.</li>
+ <li>In <strong>Android Studio</strong>, select your project and click <strong>Run</strong>
+ <img src="{@docRoot}images/tools/as-run.png" style="vertical-align:baseline;margin:0; max-height:1em" />
+ from the toolbar.</li>
+ <li>In the <strong>Choose Device</strong> window, click the <strong>Launch emulator</strong> radio
+ button.</li>
+ <li>From the <strong>Android virtual device</strong> pull-down menu, select the emulator
+ you created, and click <strong>OK</strong>.</li>
</ol>
-<p>Eclipse installs the app on your AVD and starts it.</p>
+<p>It can take a few minutes for the emulator to load itself. You may have to unlock the screen.
+ When you do, My First App appears on the emulator screen.</p>
-<p>Or to run your app from the command line:</p>
+<h3>Run your app from the command line</h3>
<ol>
<li>Change directories to the root of your Android project and execute:
-<pre class="no-pretty-print">ant debug</pre></li>
+ <pre class="no-pretty-print">ant debug</pre></li>
<li>Make sure the Android SDK <code>platform-tools/</code> directory is included in your
-<code>PATH</code> environment
-variable, then execute:
-<pre class="no-pretty-print">adb install bin/MyFirstApp-debug.apk</pre></li>
- <li>On the emulator, locate <em>MyFirstActivity</em> and open it.</li>
+ <code>PATH</code> environment variable, then execute:
+ <pre class="no-pretty-print">adb install bin/MyFirstApp-debug.apk</pre></li>
+ <li>On the emulator, locate <em>MyFirstApp</em> and open it.</li>
</ol>
-<p>That's how you build and run your Android app on the emulator!
+<p>That's how you build and run your Android app on the emulator!
To start developing, continue to the <a href="building-ui.html">next
lesson</a>.</p>
diff --git a/docs/html/training/basics/firstapp/starting-activity.jd b/docs/html/training/basics/firstapp/starting-activity.jd
index 71f66dd..7aad894 100644
--- a/docs/html/training/basics/firstapp/starting-activity.jd
+++ b/docs/html/training/basics/firstapp/starting-activity.jd
@@ -19,7 +19,7 @@
<ol>
<li><a href="#RespondToButton">Respond to the Send Button</a></li>
<li><a href="#BuildIntent">Build an Intent</a></li>
- <li><a href="#StartActivity">Start the Second Activity</a></li>
+ <!-- <li><a href="#StartActivity">Start the Second Activity</a></li> -->
<li><a href="#CreateActivity">Create the Second Activity</a></li>
<li><a href="#ReceiveIntent">Receive the Intent</a></li>
<li><a href="#DisplayMessage">Display the Message</a></li>
@@ -40,17 +40,20 @@
<p>After completing the <a href="building-ui.html">previous lesson</a>, you have an app that
shows an activity (a single screen) with a text field and a button. In this lesson, you’ll add some
-code to <code>MainActivity</code> that
+code to <code>MyActivity</code> that
starts a new activity when the user clicks the Send button.</p>
<h2 id="RespondToButton">Respond to the Send Button</h2>
-<p>To respond to the button's on-click event, open the <code>fragment_main.xml</code>
-layout file and add the <a
+<ol>
+<li>In Android Studio, from the <code>res/layout</code> directory, edit the <code>activity_my.xml</code>
+file.</li>
+<li>To the {@link android.widget.Button <Button>} element, add the <a
href="{@docRoot}reference/android/view/View.html#attr_android:onClick">{@code android:onClick}</a>
-attribute to the {@link android.widget.Button <Button>} element:</p>
+attribute.
+<p class="code-caption">res/layout/activity_my.xml</p>
<pre>
<Button
android:layout_width="wrap_content"
@@ -63,10 +66,12 @@
href="{@docRoot}reference/android/view/View.html#attr_android:onClick">{@code
android:onClick}</a> attribute’s value, <code>"sendMessage"</code>, is the name of a method in your
activity that the system calls when the user clicks the button.</p>
+</li>
+<li>In the <code>java/com.mycompany.myfirstapp</code> directory, open the <code>MyActivity.java</code> file.</li>
+<li>Within the <code>MyActivity</code> class, add the {@code sendMessage()} method stub shown
+below.
-<p>Open the <code>MainActivity</code> class (located in the project's
-<code>src/</code> directory) and add the corresponding method:</p>
-
+<p class="code-caption">java/com.mycompany.myfirstapp/MyActivity.java</p>
<pre>
/** Called when the user clicks the Send button */
public void sendMessage(View view) {
@@ -85,32 +90,40 @@
android.view.View} that was clicked)</li>
</ul>
+</li>
+</ol>
+
<p>Next, you’ll fill in this method to read the contents of the text field and deliver that text to
another activity.</p>
-
-
<h2 id="BuildIntent">Build an Intent</h2>
+<ol>
+<li>In <code>MyActivity.java</code>, inside the {@code sendMessage()} method, create an
+{@link android.content.Intent} to start an activity called {@code DisplayMessageActivity} with the
+following code:
+
+<p class="code-caption">java/com.mycompany.myfirstapp/MyActivity.java</p>
+<pre>
+public void sendMessage(View view) {
+ Intent intent = new Intent(this, DisplayMessageActivity.class);
+}
+</pre>
+
+<div class="sidebox-wrapper">
+<div class="sidebox">
+<h3>Intents</h3>
<p>An {@link android.content.Intent} is an object that provides runtime binding between separate
components (such as two activities). The {@link android.content.Intent} represents an
app’s "intent to do something." You can use intents for a wide
-variety of tasks, but most often they’re used to start another activity.</p>
+variety of tasks, but most often they’re used to start another activity. For more information, see
+<a href="{@docRoot}guide/components/intents-filters.html ">Intents and Intent Filters</a>.</p>
+</div>
+</div>
-<p>Inside the {@code sendMessage()} method, create an {@link android.content.Intent} to start
-an activity called {@code DisplayMessageActivity}:</p>
-
-<pre>
-Intent intent = new Intent(this, DisplayMessageActivity.class);
-</pre>
-
-<p>This requires that you import the {@link android.content.Intent} class:</p>
-<pre>
-import android.content.Intent;
-</pre>
-
-<p class="note"><strong>Tip:</strong> In Eclipse, press Ctrl + Shift + O to import missing classes
-(Cmd + Shift + O on Mac).</p>
+<p class="note"><strong>Note:</strong> The reference to {@code DisplayMessageActivity}
+will raise an error if you’re using an IDE such as Android Studio because the class doesn’t exist yet.
+Ignore the error for now; you’ll create the class soon.</p>
<p>The constructor used here takes two parameters:</p>
<ul>
@@ -121,6 +134,19 @@
the {@link android.content.Intent} (in this case, the activity that should be started)
</ul>
+<p>Android Studio indicates that you must import the {@link android.content.Intent} class.</p>
+
+</li>
+<li>At the top of the file, import the {@link android.content.Intent} class:
+<p class="code-caption">java/com.mycompany.myfirstapp/MyActivity.java</p>
+<pre>
+import android.content.Intent;
+</pre>
+<p class="note"><strong>Tip:</strong> In Android Studio, press Alt + Enter (option + return on Mac)
+ to import missing classes.</p>
+</li>
+
+<!-- I didn't think this was necessary
<div class="sidebox-wrapper">
<div class="sidebox">
<h3>Sending an intent to other apps</h3>
@@ -134,59 +160,69 @@
href="{@docRoot}training/basics/intents/index.html">Interacting with Other Apps</a>.</p>
</div>
</div>
+-->
-<p class="note"><strong>Note:</strong> The reference to {@code DisplayMessageActivity}
-will raise an error if you’re using an IDE such as Eclipse because the class doesn’t exist yet.
-Ignore the error for now; you’ll create the class soon.</p>
-
-<p>An intent not only allows you to start another activity, but it can carry a bundle of data to the
-activity as well. Inside the {@code sendMessage()} method,
+<li>Inside the {@code sendMessage()} method,
use {@link android.app.Activity#findViewById findViewById()} to get the
-{@link android.widget.EditText} element and add its text value to the intent:</p>
-
+{@link android.widget.EditText} element.
+<p class="code-caption">java/com.mycompany.myfirstapp/MyActivity.java</p>
<pre>
-Intent intent = new Intent(this, DisplayMessageActivity.class);
-EditText editText = (EditText) findViewById(R.id.edit_message);
-String message = editText.getText().toString();
-intent.putExtra(EXTRA_MESSAGE, message);
+public void sendMessage(View view) {
+ Intent intent = new Intent(this, DisplayMessageActivity.class);
+ EditText editText = (EditText) findViewById(R.id.edit_message);
+}
+</pre>
+</li>
+
+<li>At the top of the file, import the {@link android.widget.EditText} class.
+ <p>In Android Studio, press Alt + Enter (option + return on Mac) to import missing classes.</p>
+</li>
+
+<li>Assign the text to a local <code>message</code> variable, and use the
+{@link android.content.Intent#putExtra putExtra()} method to add its text value to the intent.
+<p class="code-caption">java/com.mycompany.myfirstapp/MyActivity.java</p>
+<pre>
+public void sendMessage(View view) {
+ Intent intent = new Intent(this, DisplayMessageActivity.class);
+ EditText editText = (EditText) findViewById(R.id.edit_message);
+ String message = editText.getText().toString();
+ intent.putExtra(EXTRA_MESSAGE, message);
+}
</pre>
-<p class="note"><strong>Note:</strong>
-You now need an import statement for <code>android.widget.EditText</code>.
-You'll define the <code>EXTRA_MESSAGE</code> constant in a moment.</p>
-
-<p>An {@link android.content.Intent} can carry a collection of various data types as key-value
+<p>An {@link android.content.Intent} can carry data types as key-value
pairs called <em>extras</em>. The {@link android.content.Intent#putExtra putExtra()} method takes the
key name in the first parameter and the value in the second parameter.</p>
-<p>In order for the next activity to query the extra data, you should define the key
-for your intent's extra using a
-public constant. So add the {@code EXTRA_MESSAGE} definition to the top of the {@code
-MainActivity} class:</p>
-
+</li>
+<li>At the top of the {@code MyActivity} class, add the {@code EXTRA_MESSAGE} definition as
+follows:
+<p class="code-caption">java/com.mycompany.myfirstapp/MyActivity.java</p>
<pre>
-public class MainActivity extends ActionBarActivity {
- public final static String EXTRA_MESSAGE = "com.example.myfirstapp.MESSAGE";
+public class MyActivity extends ActionBarActivity {
+ public final static String EXTRA_MESSAGE = "com.mycompany.myfirstapp.MESSAGE";
...
}
</pre>
-<p>It's generally a good practice to define keys for intent extras using your app's package name
-as a prefix. This ensures they are unique, in case your app interacts with other apps.</p>
+<p>For the next activity to query the extra data, you should define the key
+for your intent's extra using a public constant. It's generally a good practice to define keys for
+intent extras using your app's package name as a prefix. This ensures the keys are unique, in case
+your app interacts with other apps.</p>
+</li>
+<!-- <h2 id="StartActivity">Start the Second Activity</h2> -->
+<li>In the {@code sendMessage()} method, to finish the intent, call the
+{@link android.app.Activity#startActivity startActivity()} method, passing it the
+{@link android.content.Intent} object created in step 1.
-<h2 id="StartActivity">Start the Second Activity</h2>
-
-<p>To start an activity, call {@link android.app.Activity#startActivity
-startActivity()} and pass it your {@link android.content.Intent}. The system receives this call
-and starts an instance of the {@link android.app.Activity}
-specified by the {@link android.content.Intent}.</p>
+</ol>
<p>With this new code, the complete {@code sendMessage()} method that's invoked by the Send
button now looks like this:</p>
-
+<p class="code-caption">java/com.mycompany.myfirstapp/MyActivity.java</p>
<pre>
/** Called when the user clicks the Send button */
public void sendMessage(View view) {
@@ -198,70 +234,92 @@
}
</pre>
-<p>Now you need to create the {@code DisplayMessageActivity} class in order for this to
-work.</p>
+<p>The system receives this call and starts an instance of the {@link android.app.Activity}
+specified by the {@link android.content.Intent}. Now you need to create the
+{@code DisplayMessageActivity} class in order for this to work.</p>
+</li>
+</ol>
<h2 id="CreateActivity">Create the Second Activity</h2>
+<p>All subclasses of {@link android.app.Activity} must implement the
+{@link android.app.Activity#onCreate onCreate()} method. This method is where the activity receives
+the intent with the message, then renders the message. Also, the
+{@link android.app.Activity#onCreate onCreate()} method must define the activity
+layout with the {@link android.app.Activity#setContentView setContentView()} method. This is where
+the activity performs the initial setup of the activity components.</p>
+
+<h3>Create a new activity using Android Studio</h3>
+
<div class="figure" style="width:400px">
-<img src="{@docRoot}images/training/firstapp/adt-new-activity.png" alt="" />
-<p class="img-caption"><strong>Figure 1.</strong> The new activity wizard in Eclipse.</p>
+<img src="{@docRoot}images/training/firstapp/studio-new-activity.png" alt="" />
+<p class="img-caption"><strong>Figure 1.</strong> The new activity wizard in Android Studio.</p>
</div>
-<p>To create a new activity using Eclipse:</p>
+<p>Android Studio includes a stub for the
+{@link android.app.Activity#onCreate onCreate()} method when you create a new activity.</p>
<ol>
- <li>Click <strong>New</strong> <img src="{@docRoot}images/tools/eclipse-new.png"
- style="vertical-align:baseline;margin:0" /> in the toolbar.</li>
- <li>In the window that appears, open the <strong>Android</strong> folder
- and select <strong>Android Activity</strong>. Click <strong>Next</strong>.</li>
- <li>Select <strong>BlankActivity</strong> and click <strong>Next</strong>.</li>
- <li>Fill in the activity details:
+ <li>In Android Studio, in the <code>java</code> directory, select the package,
+ <strong>com.mycompany.myfirstapp</strong>, right-click, and select
+ <strong>New > Activity > Blank Activity</strong>.</li>
+ <li>In the <strong>Choose options</strong> window, fill in the activity details:
<ul>
- <li><strong>Project</strong>: MyFirstApp</li>
<li><strong>Activity Name</strong>: DisplayMessageActivity</li>
<li><strong>Layout Name</strong>: activity_display_message</li>
- <li><strong>Fragment Layout Name</strong>: fragment_display_message</li>
<li><strong>Title</strong>: My Message</li>
- <li><strong>Hierarchial Parent</strong>: com.example.myfirstapp.MainActivity</li>
- <li><strong>Navigation Type</strong>: None</li>
+ <li><strong>Hierarchical Parent</strong>: com.mycompany.myfirstapp.MyActivity</li>
+ <li><strong>Package name</strong>: com.mycompany.myfirstapp</li>
</ul>
<p>Click <strong>Finish</strong>.</p>
</li>
+
+<li>Open the {@code DisplayMessageActivity.java} file.
+
+<p>The class already includes an implementation of the required
+{@link android.app.Activity#onCreate onCreate()} method. You will update the implementation of this
+method later. It also includes an implementation of
+{@link android.app.Activity#onOptionsItemSelected onOptionsItemSelected()}, which handles the action
+bar's <em>Up</em> behavior. Keep these two methods as they are for now.</p>
+
+<!-- Android Studio does not create a Fragment placeholder
+<p>Also, the file includes a <code>PlaceholderFragment</code> class that extends
+{@link android.app.Fragment}. This activity does not implement fragments, but you might use this
+later in the training. Fragments decompose application functionality and UI into reusable modules.
+For more information on fragments, see the
+<a href="{@docRoot}guide/components/fragments.html">Fragments API Guide</a> and follow the training,
+<a href="{@docRoot}training/basics/fragments/index.html">Building A Dynamic UI with Fragments</a>.
+</p>
+-->
+</li>
+
+<li> Remove the {@link android.app.Activity#onCreateOptionsMenu onCreateOptionsMenu()} method.
+<p>You won't need it for this app.</p>
+</li>
</ol>
-<p>If you're using a different IDE or the command line tools, create a new file named
-{@code DisplayMessageActivity.java} in the project's <code>src/</code> directory, next to
-the original {@code MainActivity.java} file.</p>
-
-<p>Open the {@code DisplayMessageActivity.java} file. If you used Eclipse to create this
-activity:</p>
-<ul>
- <li>The class
-already includes an implementation of the required {@link android.app.Activity#onCreate onCreate()}
-method. You will update the implementation of this method later.</li>
- <li>There's also an implementation of the {@link android.app.Activity#onCreateOptionsMenu
-onCreateOptionsMenu()} method, but
-you won't need it for this app so you can remove it.</li>
- <li>There's also an implementation of {@link android.app.Activity#onOptionsItemSelected
- onOptionsItemSelected()} which handles the behavior for the action bar's <em>Up</em> behavior.
- Keep this one the way it is.</li>
- <li>There's also a <code>PlaceholderFragment</code> class that extends
-{@link android.app.Fragment}. You will not need this class in the final version of this
-activity.</li>
-</ul>
-
-<p>Fragments decompose application functionality and UI into reusable modules. For more
-information on fragments, see the <a href="{@docRoot}guide/components/fragments.html">Fragments
-API Guide</a>. The final version of this activity does not use fragments.</p>
-
+<!-- Not needed for Android Studio
<p class="note"><strong>Note:</strong> Your activity may look different if you did not use
the latest version of the ADT plugin. Make sure you install the latest version of the
<a href="{@docRoot}tools/sdk/eclipse-adt.html">ADT plugin</a> to complete this tutorial.</p>
+-->
-<p>The {@code DisplayMessageActivity} class should now look like this:</p>
+<p>If you're developing with Android Studio, you can run the app now, but not much happens.
+Clicking the Send button starts the second activity, but it uses
+a default "Hello world" layout provided by the template. You'll soon update the
+activity to instead display a custom text view.</p>
+
+
+<h3>Create the activity without Android Studio</h3>
+
+<p>If you're using a different IDE or the command line tools, do the following:</p>
+
+<ol>
+<li>Create a new file named {@code DisplayMessageActivity.java} in the project's <code>src/</code>
+directory, next to the original {@code MyActivity.java} file.</li>
+<li>Add the following code to the file:
<pre>
public class DisplayMessageActivity extends ActionBarActivity {
@@ -307,63 +365,44 @@
}
</pre>
-<p>If you used an IDE other than Eclipse, update your {@code DisplayMessageActivity}
-class with the above code.</p>
-
-<p>All subclasses of {@link android.app.Activity} must implement the {@link
-android.app.Activity#onCreate onCreate()} method. The system calls this when creating a new
-instance of the activity. This method is where you must define the activity layout
-with the {@link android.app.Activity#setContentView setContentView()} method
-and is where you should
-perform initial setup for the activity components.</p>
-
-<p class="note"><strong>Note:</strong> If you are using an IDE other than Eclipse, your project
+<p class="note"><strong>Note:</strong> If you are using an IDE other than Android Studio, your project
does not contain the {@code activity_display_message} layout that's requested by
{@link android.app.Activity#setContentView setContentView()}. That's OK because
you will update this method later and won't be using that layout.</p>
+</li>
-<h3 id="AddTitle">Add the title string</h3>
-
-<p>If you used Eclipse, you can skip to the <a href="#AddToManifest">next section</a>,
-because the template provides
-the title string for the new activity.</p>
-
-<p>If you're using an IDE other than Eclipse,
-add the new activity's title to the {@code strings.xml} file:</p>
+<li>To your {@code strings.xml} file, add the new activity's title as follows:
<pre>
<resources>
...
<string name="title_activity_display_message">My Message</string>
</resources>
</pre>
+</li>
-
-
-<h3 id="AddToManifest">Add it to the manifest</h3>
-
-<p>All activities must be declared in your manifest file, <code>AndroidManifest.xml</code>, using an
-<a
-href="{@docRoot}guide/topics/manifest/activity-element.html">{@code <activity>}</a> element.</p>
-
-<p>When you use the Eclipse tools to create the activity, it creates a default entry. If you're
-using a different IDE, you need to add the manifest entry yourself. It should
-look like this:</p>
+<li>In your manifest file, <code>AndroidManifest.xml</code>, within the <code>Application</code>
+element, add the
+<a href="{@docRoot}guide/topics/manifest/activity-element.html">{@code <activity>}</a> element
+for your {@code DisplayMessageActivity} class, as follows:
<pre>
<application ... >
...
<activity
- android:name="com.example.myfirstapp.DisplayMessageActivity"
+ android:name="com.mycompany.myfirstapp.DisplayMessageActivity"
android:label="@string/title_activity_display_message"
- android:parentActivityName="com.example.myfirstapp.MainActivity" >
+ android:parentActivityName="com.mycompany.myfirstapp.MyActivity" >
<meta-data
android:name="android.support.PARENT_ACTIVITY"
- android:value="com.example.myfirstapp.MainActivity" />
+ android:value="com.mycompany.myfirstapp.MyActivity" />
</activity>
</application>
</pre>
+</li>
+</ol>
+
<p>The <a href="{@docRoot}guide/topics/manifest/activity-element.html#parent">{@code
android:parentActivityName}</a> attribute declares the name of this activity's parent activity
within the app's logical hierarchy. The system uses this value
@@ -376,20 +415,16 @@
<meta-data>}</a> element as shown here.</p>
<p class="note"><strong>Note:</strong> Your Android SDK should already include
-the latest Android Support Library. It's included with the ADT Bundle but if you're using
-a different IDE, you should have installed it during the
-<a href="{@docRoot}sdk/installing/adding-packages.html">Adding Platforms and Packages</a> step.
-When using the templates in Eclipse, the Support Library is automatically added to your app project
+the latest Android Support Library, which you installed during the
+<a href="{@docRoot}sdk/installing/adding-packages.html">Adding SDK Packages</a> step.
+When using the templates in Android Studio, the Support Library is automatically added to your app project
(you can see the library's JAR file listed under <em>Android Dependencies</em>). If you're not using
-Eclipse, you need to manually add the library to your project—follow the guide for <a
+Android Studio, you need to manually add the library to your project—follow the guide for <a
href="{@docRoot}tools/support-library/setup.html">setting up the Support Library</a>
then return here.</p>
-<p>If you're developing with Eclipse, you can run the app now, but not much happens.
-Clicking the Send button starts the second activity but it uses
-a default "Hello world" layout provided by the template. You'll soon update the
-activity to instead display a custom text view, so if you're using a different IDE,
-don't worry that the app won't yet compile.</p>
+<p>If you're using a different IDE than Android Studio, don't worry that the app won't yet compile.
+You'll soon update the activity to display a custom text view.</p>
<h2 id="ReceiveIntent">Receive the Intent</h2>
@@ -397,24 +432,55 @@
<p>Every {@link android.app.Activity} is invoked by an {@link android.content.Intent}, regardless of
how the user navigated there. You can get the {@link android.content.Intent} that started your
activity by calling {@link android.app.Activity#getIntent()} and retrieve the data contained
-within it.</p>
+within the intent.</p>
-<p>In the {@code DisplayMessageActivity} class’s {@link android.app.Activity#onCreate onCreate()}
-method, get the intent and extract the message delivered by {@code MainActivity}:</p>
-
+<ol>
+<li>In the <code>java/com.mycompany.myfirstapp</code> directory, edit the
+ {@code DisplayMessageActivity.java} file.</li>
+<li>In the {@link android.app.Activity#onCreate onCreate()} method, remove the following line:
+<pre>
+ setContentView(R.layout.activity_display_message);
+</pre>
+<li>Get the intent and assign it to a local variable.
<pre>
Intent intent = getIntent();
-String message = intent.getStringExtra(MainActivity.EXTRA_MESSAGE);
</pre>
-
-
+</li>
+<li>At the top of the file, import the {@link android.content.Intent} class.
+ <p>In Android Studio, press Alt + Enter (option + return on Mac) to import missing classes.</p>
+</li>
+<li>Extract the message delivered by {@code MyActivity} with the
+{@link android.content.Intent#getStringExtra getStringExtra()} method.
+<pre>
+String message = intent.getStringExtra(MyActivity.EXTRA_MESSAGE);
+</pre>
+</li>
+</ol>
<h2 id="DisplayMessage">Display the Message</h2>
-<p>To show the message on the screen, create a {@link android.widget.TextView} widget and set the
-text using {@link android.widget.TextView#setText setText()}. Then add the {@link
-android.widget.TextView} as the root view of the activity’s layout by passing it to {@link
-android.app.Activity#setContentView setContentView()}.</p>
+<ol>
+<li>In the {@link android.app.Activity#onCreate onCreate()} method, create a {@link android.widget.TextView} object.
+<pre>
+TextView textView = new TextView(this);
+</pre>
+</li>
+<li>Set the text size and message with {@link android.widget.TextView#setText setText()}.
+<pre>
+textView.setTextSize(40);
+textView.setText(message);
+</pre>
+</li>
+<li>Then add the {@link android.widget.TextView} as the root view of the activity’s layout by
+passing it to {@link android.app.Activity#setContentView setContentView()}.
+<pre>
+setContentView(textView);
+</pre>
+</li>
+<li>At the top of the file, import the {@link android.widget.TextView} class.
+ <p>In Android Studio, press Alt + Enter (option + return on Mac) to import missing classes.</p>
+</li>
+</ol>
<p>The complete {@link android.app.Activity#onCreate onCreate()} method for {@code
DisplayMessageActivity} now looks like this:</p>
@@ -426,7 +492,7 @@
// Get the message from the intent
Intent intent = getIntent();
- String message = intent.getStringExtra(MainActivity.EXTRA_MESSAGE);
+ String message = intent.getStringExtra(MyActivity.EXTRA_MESSAGE);
// Create the text view
TextView textView = new TextView(this);
diff --git a/docs/html/wear/design/index.jd b/docs/html/wear/design/index.jd
index 247cc87..e01d17f 100644
--- a/docs/html/wear/design/index.jd
+++ b/docs/html/wear/design/index.jd
@@ -164,7 +164,7 @@
<img src="{@docRoot}wear/images/circle_voice_B.png" height="200" style="float:right;margin:0 0 20px 40px" />
<img src="{@docRoot}wear/images/circle_voice_A.png" height="200" style="float:right;margin:0 0 20px 40px" />
-<p>Voice replies are primarily used by messaging applications to provide a hands-free way of dictating a short message. You can also provide a up to five suggested replies or “canned responses” that are useful in a wide range of cases. These canned responses can be tapped by the user, allowing for a fast method of sending simple replies in cases where speaking may not be desirable.</p>
+<p>Voice replies are primarily used by messaging applications to provide a hands-free way of dictating a short message. You can also provide up to five suggested replies or “canned responses” that are useful in a wide range of cases. These canned responses can be tapped by the user, allowing for a fast method of sending simple replies in cases where speaking may not be desirable.</p>
<p>You should attempt to cover a range of simple, neutral replies in your choices. Longer voice replies may be automatically truncated in the Voice reply UI.</p>
diff --git a/drm/jni/Android.mk b/drm/jni/Android.mk
index 474b9b2..08c7b95 100644
--- a/drm/jni/Android.mk
+++ b/drm/jni/Android.mk
@@ -39,8 +39,8 @@
$(TOP)/frameworks/av/include \
$(TOP)/libcore/include
-
-
LOCAL_MODULE_TAGS := optional
+LOCAL_CFLAGS += -Wall -Werror -Wunused -Wunreachable-code
+
include $(BUILD_SHARED_LIBRARY)
diff --git a/drm/jni/android_drm_DrmManagerClient.cpp b/drm/jni/android_drm_DrmManagerClient.cpp
index d321baf..52597e1 100644
--- a/drm/jni/android_drm_DrmManagerClient.cpp
+++ b/drm/jni/android_drm_DrmManagerClient.cpp
@@ -381,7 +381,8 @@
}
static void android_drm_DrmManagerClient_installDrmEngine(
- JNIEnv* env, jobject thiz, jint uniqueId, jstring engineFilePath) {
+ JNIEnv* /* env */, jobject /* thiz */, jint /* uniqueId */,
+ jstring /* engineFilePath */) {
ALOGV("installDrmEngine - Enter");
//getDrmManagerClient(env, thiz)
// ->installDrmEngine(uniqueId, Utility::getStringValue(env, engineFilePath));
@@ -776,7 +777,7 @@
return result;
}
-jint JNI_OnLoad(JavaVM* vm, void* reserved) {
+jint JNI_OnLoad(JavaVM* vm, void* /* reserved */) {
JNIEnv* env = NULL;
jint result = -1;
diff --git a/graphics/java/android/graphics/Bitmap.java b/graphics/java/android/graphics/Bitmap.java
index 3090ffd8..004d0ae 100644
--- a/graphics/java/android/graphics/Bitmap.java
+++ b/graphics/java/android/graphics/Bitmap.java
@@ -1542,7 +1542,7 @@
*/
public Bitmap extractAlpha(Paint paint, int[] offsetXY) {
checkRecycled("Can't extractAlpha on a recycled bitmap");
- long nativePaint = paint != null ? paint.mNativePaint : 0;
+ long nativePaint = paint != null ? paint.getNativeInstance() : 0;
Bitmap bm = nativeExtractAlpha(mNativeBitmap, nativePaint, offsetXY);
if (bm == null) {
throw new RuntimeException("Failed to extractAlpha on Bitmap");
diff --git a/graphics/java/android/graphics/Canvas.java b/graphics/java/android/graphics/Canvas.java
index f45c0cb..edf0fb9 100644
--- a/graphics/java/android/graphics/Canvas.java
+++ b/graphics/java/android/graphics/Canvas.java
@@ -430,7 +430,7 @@
public int saveLayer(float left, float top, float right, float bottom, @Nullable Paint paint,
@Saveflags int saveFlags) {
return native_saveLayer(mNativeCanvasWrapper, left, top, right, bottom,
- paint != null ? paint.mNativePaint : 0,
+ paint != null ? paint.getNativeInstance() : 0,
saveFlags);
}
@@ -974,7 +974,7 @@
* @param paint The paint used to draw onto the canvas
*/
public void drawPaint(@NonNull Paint paint) {
- native_drawPaint(mNativeCanvasWrapper, paint.mNativePaint);
+ native_drawPaint(mNativeCanvasWrapper, paint.getNativeInstance());
}
/**
@@ -994,7 +994,7 @@
* @param paint The paint used to draw the points
*/
public void drawPoints(float[] pts, int offset, int count, @NonNull Paint paint) {
- native_drawPoints(mNativeCanvasWrapper, pts, offset, count, paint.mNativePaint);
+ native_drawPoints(mNativeCanvasWrapper, pts, offset, count, paint.getNativeInstance());
}
/**
@@ -1008,7 +1008,7 @@
* Helper for drawPoints() for drawing a single point.
*/
public void drawPoint(float x, float y, @NonNull Paint paint) {
- native_drawPoint(mNativeCanvasWrapper, x, y, paint.mNativePaint);
+ native_drawPoint(mNativeCanvasWrapper, x, y, paint.getNativeInstance());
}
/**
@@ -1025,7 +1025,7 @@
*/
public void drawLine(float startX, float startY, float stopX, float stopY,
@NonNull Paint paint) {
- native_drawLine(mNativeCanvasWrapper, startX, startY, stopX, stopY, paint.mNativePaint);
+ native_drawLine(mNativeCanvasWrapper, startX, startY, stopX, stopY, paint.getNativeInstance());
}
/**
@@ -1044,7 +1044,7 @@
* @param paint The paint used to draw the points
*/
public void drawLines(float[] pts, int offset, int count, Paint paint) {
- native_drawLines(mNativeCanvasWrapper, pts, offset, count, paint.mNativePaint);
+ native_drawLines(mNativeCanvasWrapper, pts, offset, count, paint.getNativeInstance());
}
public void drawLines(@NonNull float[] pts, @NonNull Paint paint) {
@@ -1060,7 +1060,7 @@
*/
public void drawRect(@NonNull RectF rect, @NonNull Paint paint) {
native_drawRect(mNativeCanvasWrapper,
- rect.left, rect.top, rect.right, rect.bottom, paint.mNativePaint);
+ rect.left, rect.top, rect.right, rect.bottom, paint.getNativeInstance());
}
/**
@@ -1086,7 +1086,7 @@
* @param paint The paint used to draw the rect
*/
public void drawRect(float left, float top, float right, float bottom, @NonNull Paint paint) {
- native_drawRect(mNativeCanvasWrapper, left, top, right, bottom, paint.mNativePaint);
+ native_drawRect(mNativeCanvasWrapper, left, top, right, bottom, paint.getNativeInstance());
}
/**
@@ -1107,7 +1107,7 @@
* filled or framed based on the Style in the paint.
*/
public void drawOval(float left, float top, float right, float bottom, @NonNull Paint paint) {
- native_drawOval(mNativeCanvasWrapper, left, top, right, bottom, paint.mNativePaint);
+ native_drawOval(mNativeCanvasWrapper, left, top, right, bottom, paint.getNativeInstance());
}
/**
@@ -1121,7 +1121,7 @@
* @param paint The paint used to draw the circle
*/
public void drawCircle(float cx, float cy, float radius, @NonNull Paint paint) {
- native_drawCircle(mNativeCanvasWrapper, cx, cy, radius, paint.mNativePaint);
+ native_drawCircle(mNativeCanvasWrapper, cx, cy, radius, paint.getNativeInstance());
}
/**
@@ -1177,7 +1177,7 @@
public void drawArc(float left, float top, float right, float bottom, float startAngle,
float sweepAngle, boolean useCenter, @NonNull Paint paint) {
native_drawArc(mNativeCanvasWrapper, left, top, right, bottom, startAngle, sweepAngle,
- useCenter, paint.mNativePaint);
+ useCenter, paint.getNativeInstance());
}
/**
@@ -1203,7 +1203,7 @@
*/
public void drawRoundRect(float left, float top, float right, float bottom, float rx, float ry,
@NonNull Paint paint) {
- native_drawRoundRect(mNativeCanvasWrapper, left, top, right, bottom, rx, ry, paint.mNativePaint);
+ native_drawRoundRect(mNativeCanvasWrapper, left, top, right, bottom, rx, ry, paint.getNativeInstance());
}
/**
@@ -1214,7 +1214,7 @@
* @param paint The paint used to draw the path
*/
public void drawPath(@NonNull Path path, @NonNull Paint paint) {
- native_drawPath(mNativeCanvasWrapper, path.ni(), paint.mNativePaint);
+ native_drawPath(mNativeCanvasWrapper, path.ni(), paint.getNativeInstance());
}
/**
@@ -1279,7 +1279,7 @@
public void drawBitmap(@NonNull Bitmap bitmap, float left, float top, @Nullable Paint paint) {
throwIfCannotDraw(bitmap);
native_drawBitmap(mNativeCanvasWrapper, bitmap.ni(), left, top,
- paint != null ? paint.mNativePaint : 0, mDensity, mScreenDensity, bitmap.mDensity);
+ paint != null ? paint.getNativeInstance() : 0, mDensity, mScreenDensity, bitmap.mDensity);
}
/**
@@ -1310,7 +1310,7 @@
throw new NullPointerException();
}
throwIfCannotDraw(bitmap);
- final long nativePaint = paint == null ? 0 : paint.mNativePaint;
+ final long nativePaint = paint == null ? 0 : paint.getNativeInstance();
float left, top, right, bottom;
if (src == null) {
@@ -1357,7 +1357,7 @@
throw new NullPointerException();
}
throwIfCannotDraw(bitmap);
- final long nativePaint = paint == null ? 0 : paint.mNativePaint;
+ final long nativePaint = paint == null ? 0 : paint.getNativeInstance();
int left, top, right, bottom;
if (src == null) {
@@ -1425,7 +1425,7 @@
}
// punch down to native for the actual draw
native_drawBitmap(mNativeCanvasWrapper, colors, offset, stride, x, y, width, height, hasAlpha,
- paint != null ? paint.mNativePaint : 0);
+ paint != null ? paint.getNativeInstance() : 0);
}
/**
@@ -1453,7 +1453,7 @@
*/
public void drawBitmap(@NonNull Bitmap bitmap, @NonNull Matrix matrix, @Nullable Paint paint) {
nativeDrawBitmapMatrix(mNativeCanvasWrapper, bitmap.ni(), matrix.ni(),
- paint != null ? paint.mNativePaint : 0);
+ paint != null ? paint.getNativeInstance() : 0);
}
/**
@@ -1509,7 +1509,7 @@
}
nativeDrawBitmapMesh(mNativeCanvasWrapper, bitmap.ni(), meshWidth, meshHeight,
verts, vertOffset, colors, colorOffset,
- paint != null ? paint.mNativePaint : 0);
+ paint != null ? paint.getNativeInstance() : 0);
}
public enum VertexMode {
@@ -1573,7 +1573,7 @@
}
nativeDrawVertices(mNativeCanvasWrapper, mode.nativeInt, vertexCount, verts,
vertOffset, texs, texOffset, colors, colorOffset,
- indices, indexOffset, indexCount, paint.mNativePaint);
+ indices, indexOffset, indexCount, paint.getNativeInstance());
}
/**
@@ -1592,7 +1592,7 @@
throw new IndexOutOfBoundsException();
}
native_drawText(mNativeCanvasWrapper, text, index, count, x, y, paint.mBidiFlags,
- paint.mNativePaint, paint.mNativeTypeface);
+ paint.getNativeInstance(), paint.mNativeTypeface);
}
/**
@@ -1606,7 +1606,7 @@
*/
public void drawText(@NonNull String text, float x, float y, @NonNull Paint paint) {
native_drawText(mNativeCanvasWrapper, text, 0, text.length(), x, y, paint.mBidiFlags,
- paint.mNativePaint, paint.mNativeTypeface);
+ paint.getNativeInstance(), paint.mNativeTypeface);
}
/**
@@ -1626,7 +1626,7 @@
throw new IndexOutOfBoundsException();
}
native_drawText(mNativeCanvasWrapper, text, start, end, x, y, paint.mBidiFlags,
- paint.mNativePaint, paint.mNativeTypeface);
+ paint.getNativeInstance(), paint.mNativeTypeface);
}
/**
@@ -1647,7 +1647,7 @@
if (text instanceof String || text instanceof SpannedString ||
text instanceof SpannableString) {
native_drawText(mNativeCanvasWrapper, text.toString(), start, end, x, y,
- paint.mBidiFlags, paint.mNativePaint, paint.mNativeTypeface);
+ paint.mBidiFlags, paint.getNativeInstance(), paint.mNativeTypeface);
} else if (text instanceof GraphicsOperations) {
((GraphicsOperations) text).drawText(this, start, end, x, y,
paint);
@@ -1655,7 +1655,7 @@
char[] buf = TemporaryBuffer.obtain(end - start);
TextUtils.getChars(text, start, end, buf, 0);
native_drawText(mNativeCanvasWrapper, buf, 0, end - start, x, y,
- paint.mBidiFlags, paint.mNativePaint, paint.mNativeTypeface);
+ paint.mBidiFlags, paint.getNativeInstance(), paint.mNativeTypeface);
TemporaryBuffer.recycle(buf);
}
}
@@ -1694,7 +1694,7 @@
}
native_drawTextRun(mNativeCanvasWrapper, text, index, count,
- contextIndex, contextCount, x, y, isRtl, paint.mNativePaint, paint.mNativeTypeface);
+ contextIndex, contextCount, x, y, isRtl, paint.getNativeInstance(), paint.mNativeTypeface);
}
/**
@@ -1730,7 +1730,7 @@
if (text instanceof String || text instanceof SpannedString ||
text instanceof SpannableString) {
native_drawTextRun(mNativeCanvasWrapper, text.toString(), start, end,
- contextStart, contextEnd, x, y, isRtl, paint.mNativePaint, paint.mNativeTypeface);
+ contextStart, contextEnd, x, y, isRtl, paint.getNativeInstance(), paint.mNativeTypeface);
} else if (text instanceof GraphicsOperations) {
((GraphicsOperations) text).drawTextRun(this, start, end,
contextStart, contextEnd, x, y, isRtl, paint);
@@ -1740,7 +1740,7 @@
char[] buf = TemporaryBuffer.obtain(contextLen);
TextUtils.getChars(text, contextStart, contextEnd, buf, 0);
native_drawTextRun(mNativeCanvasWrapper, buf, start - contextStart, len,
- 0, contextLen, x, y, isRtl, paint.mNativePaint, paint.mNativeTypeface);
+ 0, contextLen, x, y, isRtl, paint.getNativeInstance(), paint.mNativeTypeface);
TemporaryBuffer.recycle(buf);
}
}
@@ -1808,7 +1808,7 @@
}
native_drawTextOnPath(mNativeCanvasWrapper, text, index, count,
path.ni(), hOffset, vOffset,
- paint.mBidiFlags, paint.mNativePaint, paint.mNativeTypeface);
+ paint.mBidiFlags, paint.getNativeInstance(), paint.mNativeTypeface);
}
/**
@@ -1828,7 +1828,7 @@
float vOffset, @NonNull Paint paint) {
if (text.length() > 0) {
native_drawTextOnPath(mNativeCanvasWrapper, text, path.ni(), hOffset, vOffset,
- paint.mBidiFlags, paint.mNativePaint, paint.mNativeTypeface);
+ paint.mBidiFlags, paint.getNativeInstance(), paint.mNativeTypeface);
}
}
diff --git a/graphics/java/android/graphics/CanvasProperty.java b/graphics/java/android/graphics/CanvasProperty.java
index be86060..ea3886c 100644
--- a/graphics/java/android/graphics/CanvasProperty.java
+++ b/graphics/java/android/graphics/CanvasProperty.java
@@ -31,7 +31,7 @@
}
public static CanvasProperty<Paint> createPaint(Paint initialValue) {
- return new CanvasProperty<Paint>(nCreatePaint(initialValue.mNativePaint));
+ return new CanvasProperty<Paint>(nCreatePaint(initialValue.getNativeInstance()));
}
private CanvasProperty(long nativeContainer) {
diff --git a/graphics/java/android/graphics/ColorMatrix.java b/graphics/java/android/graphics/ColorMatrix.java
index 1242eb5..f73abcb 100644
--- a/graphics/java/android/graphics/ColorMatrix.java
+++ b/graphics/java/android/graphics/ColorMatrix.java
@@ -16,8 +16,6 @@
package android.graphics;
-import android.util.FloatMath;
-
import java.util.Arrays;
/**
@@ -123,9 +121,9 @@
*/
public void setRotate(int axis, float degrees) {
reset();
- float radians = degrees * (float)Math.PI / 180;
- float cosine = FloatMath.cos(radians);
- float sine = FloatMath.sin(radians);
+ double radians = degrees * Math.PI / 180d;
+ float cosine = (float) Math.cos(radians);
+ float sine = (float) Math.sin(radians);
switch (axis) {
// Rotation around the red color
case 0:
diff --git a/graphics/java/android/graphics/DrawFilter.java b/graphics/java/android/graphics/DrawFilter.java
index ed38f37..aaefce9 100644
--- a/graphics/java/android/graphics/DrawFilter.java
+++ b/graphics/java/android/graphics/DrawFilter.java
@@ -24,8 +24,11 @@
*/
public class DrawFilter {
- // this is set by subclasses, but don't make it public
- /* package */ long mNativeInt; // pointer to native object
+ /**
+ * this is set by subclasses
+ * @hide
+ */
+ public long mNativeInt;
protected void finalize() throws Throwable {
try {
diff --git a/graphics/java/android/graphics/LayerRasterizer.java b/graphics/java/android/graphics/LayerRasterizer.java
index e7a24a4..b692ecf 100644
--- a/graphics/java/android/graphics/LayerRasterizer.java
+++ b/graphics/java/android/graphics/LayerRasterizer.java
@@ -28,11 +28,11 @@
object itself, so it may be reused without danger of side-effects.
*/
public void addLayer(Paint paint, float dx, float dy) {
- nativeAddLayer(native_instance, paint.mNativePaint, dx, dy);
+ nativeAddLayer(native_instance, paint.getNativeInstance(), dx, dy);
}
public void addLayer(Paint paint) {
- nativeAddLayer(native_instance, paint.mNativePaint, 0, 0);
+ nativeAddLayer(native_instance, paint.getNativeInstance(), 0, 0);
}
private static native long nativeConstructor();
diff --git a/graphics/java/android/graphics/Movie.java b/graphics/java/android/graphics/Movie.java
index b0a4553..dd5b62d 100644
--- a/graphics/java/android/graphics/Movie.java
+++ b/graphics/java/android/graphics/Movie.java
@@ -35,12 +35,16 @@
public native boolean isOpaque();
public native int duration();
- public native boolean setTime(int relativeMilliseconds);
+ public native boolean setTime(int relativeMilliseconds);
- public native void draw(Canvas canvas, float x, float y, Paint paint);
-
+ private native void nDraw(Canvas canvas, float x, float y, long paintHandle);
+
+ public void draw(Canvas canvas, float x, float y, Paint paint) {
+ nDraw(canvas, x, y, paint != null ? paint.getNativeInstance() : 0);
+ }
+
public void draw(Canvas canvas, float x, float y) {
- draw(canvas, x, y, null);
+ nDraw(canvas, x, y, 0);
}
public static Movie decodeStream(InputStream is) {
diff --git a/graphics/java/android/graphics/NinePatch.java b/graphics/java/android/graphics/NinePatch.java
index 6f42046..ebc86aa 100644
--- a/graphics/java/android/graphics/NinePatch.java
+++ b/graphics/java/android/graphics/NinePatch.java
@@ -200,12 +200,12 @@
void drawSoftware(Canvas canvas, RectF location, Paint paint) {
nativeDraw(canvas.getNativeCanvasWrapper(), location, mBitmap.ni(), mNativeChunk,
- paint != null ? paint.mNativePaint : 0, canvas.mDensity, mBitmap.mDensity);
+ paint != null ? paint.getNativeInstance() : 0, canvas.mDensity, mBitmap.mDensity);
}
void drawSoftware(Canvas canvas, Rect location, Paint paint) {
nativeDraw(canvas.getNativeCanvasWrapper(), location, mBitmap.ni(), mNativeChunk,
- paint != null ? paint.mNativePaint : 0, canvas.mDensity, mBitmap.mDensity);
+ paint != null ? paint.getNativeInstance() : 0, canvas.mDensity, mBitmap.mDensity);
}
/**
diff --git a/graphics/java/android/graphics/Paint.java b/graphics/java/android/graphics/Paint.java
index 652fe64..91c8dba 100644
--- a/graphics/java/android/graphics/Paint.java
+++ b/graphics/java/android/graphics/Paint.java
@@ -29,10 +29,9 @@
*/
public class Paint {
- /**
- * @hide
- */
- public long mNativePaint;
+ private long mNativePaint;
+ private long mNativeShader = 0;
+
/**
* @hide
*/
@@ -445,7 +444,7 @@
* new paint.
*/
public Paint(Paint paint) {
- mNativePaint = native_initWithPaint(paint.mNativePaint);
+ mNativePaint = native_initWithPaint(paint.getNativeInstance());
setClassVariablesFrom(paint);
}
@@ -464,6 +463,7 @@
mPathEffect = null;
mRasterizer = null;
mShader = null;
+ mNativeShader = 0;
mTypeface = null;
mNativeTypeface = 0;
mXfermode = null;
@@ -500,11 +500,8 @@
mMaskFilter = paint.mMaskFilter;
mPathEffect = paint.mPathEffect;
mRasterizer = paint.mRasterizer;
- if (paint.mShader != null) {
- mShader = paint.mShader.copy();
- } else {
- mShader = null;
- }
+ mShader = paint.mShader;
+ mNativeShader = paint.mNativeShader;
mTypeface = paint.mTypeface;
mNativeTypeface = paint.mNativeTypeface;
mXfermode = paint.mXfermode;
@@ -531,6 +528,20 @@
}
/**
+ * Return the pointer to the native object while ensuring that any
+ * mutable objects that are attached to the paint are also up-to-date.
+ *
+ * @hide
+ */
+ public long getNativeInstance() {
+ if (mShader != null && mShader.getNativeInstance() != mNativeShader) {
+ mNativeShader = mShader.getNativeInstance();
+ native_setShader(mNativePaint, mNativeShader);
+ }
+ return mNativePaint;
+ }
+
+ /**
* Return the bidi flags on the paint.
*
* @return the bidi flags on the paint
@@ -920,10 +931,7 @@
* @return shader
*/
public Shader setShader(Shader shader) {
- long shaderNative = 0;
- if (shader != null)
- shaderNative = shader.getNativeInstance();
- native_setShader(mNativePaint, shaderNative);
+ // Defer setting the shader natively until getNativeInstance() is called
mShader = shader;
return shader;
}
diff --git a/graphics/java/android/graphics/PaintFlagsDrawFilter.java b/graphics/java/android/graphics/PaintFlagsDrawFilter.java
index 65a6218..2326611 100644
--- a/graphics/java/android/graphics/PaintFlagsDrawFilter.java
+++ b/graphics/java/android/graphics/PaintFlagsDrawFilter.java
@@ -17,11 +17,6 @@
package android.graphics;
public class PaintFlagsDrawFilter extends DrawFilter {
- /** @hide **/
- public final int clearBits;
- /** @hide **/
- public final int setBits;
-
/**
* Subclass of DrawFilter that affects every paint by first clearing
* the specified clearBits in the paint's flags, and then setting the
@@ -31,8 +26,6 @@
* @param setBits These bits will be set in the paint's flags
*/
public PaintFlagsDrawFilter(int clearBits, int setBits) {
- this.clearBits = clearBits;
- this.setBits = setBits;
// our native constructor can return 0, if the specified bits
// are effectively a no-op
mNativeInt = nativeConstructor(clearBits, setBits);
diff --git a/graphics/java/android/graphics/PointF.java b/graphics/java/android/graphics/PointF.java
index ee38dbb..8e4288e 100644
--- a/graphics/java/android/graphics/PointF.java
+++ b/graphics/java/android/graphics/PointF.java
@@ -18,7 +18,6 @@
import android.os.Parcel;
import android.os.Parcelable;
-import android.util.FloatMath;
/**
@@ -109,7 +108,7 @@
* Returns the euclidian distance from (0,0) to (x,y)
*/
public static float length(float x, float y) {
- return FloatMath.sqrt(x * x + y * y);
+ return (float) Math.hypot(x, y);
}
/**
diff --git a/graphics/java/android/graphics/RectF.java b/graphics/java/android/graphics/RectF.java
index 53178b0..f5cedfa 100644
--- a/graphics/java/android/graphics/RectF.java
+++ b/graphics/java/android/graphics/RectF.java
@@ -20,7 +20,6 @@
import android.os.Parcel;
import android.os.Parcelable;
-import android.util.FloatMath;
import com.android.internal.util.FastMath;
/**
@@ -450,8 +449,8 @@
* floor of top and left, and the ceiling of right and bottom.
*/
public void roundOut(Rect dst) {
- dst.set((int) FloatMath.floor(left), (int) FloatMath.floor(top),
- (int) FloatMath.ceil(right), (int) FloatMath.ceil(bottom));
+ dst.set((int) Math.floor(left), (int) Math.floor(top),
+ (int) Math.ceil(right), (int) Math.ceil(bottom));
}
/**
diff --git a/graphics/java/android/graphics/Shader.java b/graphics/java/android/graphics/Shader.java
index 6934955..a96d2cb 100644
--- a/graphics/java/android/graphics/Shader.java
+++ b/graphics/java/android/graphics/Shader.java
@@ -82,7 +82,8 @@
*/
public void setLocalMatrix(Matrix localM) {
mLocalMatrix = localM;
- nativeSetLocalMatrix(native_instance, localM == null ? 0 : localM.native_instance);
+ native_instance = nativeSetLocalMatrix(native_instance,
+ localM == null ? 0 : localM.native_instance);
}
protected void finalize() throws Throwable {
@@ -120,5 +121,5 @@
}
private static native void nativeDestructor(long native_shader);
- private static native void nativeSetLocalMatrix(long native_shader, long matrix_instance);
+ private static native long nativeSetLocalMatrix(long native_shader, long matrix_instance);
}
diff --git a/graphics/java/android/graphics/drawable/GradientDrawable.java b/graphics/java/android/graphics/drawable/GradientDrawable.java
index 94c7026..12b707b 100644
--- a/graphics/java/android/graphics/drawable/GradientDrawable.java
+++ b/graphics/java/android/graphics/drawable/GradientDrawable.java
@@ -492,9 +492,9 @@
/**
* <p>Sets the colors used to draw the gradient. Each color is specified as an
* ARGB integer and the array must contain at least 2 colors.</p>
- * <p><strong>Note</strong>: changing orientation will affect all instances
+ * <p><strong>Note</strong>: changing colors will affect all instances
* of a drawable loaded from a resource. It is recommended to invoke
- * {@link #mutate()} before changing the orientation.</p>
+ * {@link #mutate()} before changing the colors.</p>
*
* @param colors 2 or more ARGB colors
*
diff --git a/include/androidfw/ResourceTypes.h b/include/androidfw/ResourceTypes.h
index 6b84494..ba72cd5 100644
--- a/include/androidfw/ResourceTypes.h
+++ b/include/androidfw/ResourceTypes.h
@@ -247,8 +247,8 @@
#define Res_MAKEINTERNAL(entry) (0x01000000 | (entry&0xFFFF))
#define Res_MAKEARRAY(entry) (0x02000000 | (entry&0xFFFF))
-#define Res_MAXPACKAGE 255
-#define Res_MAXTYPE 255
+static const size_t Res_MAXPACKAGE = 255;
+static const size_t Res_MAXTYPE = 255;
/**
* Representation of a value in a resource, supplying type
@@ -1793,9 +1793,7 @@
const char* targetPath, const char* overlayPath,
void** outData, size_t* outSize) const;
- enum {
- IDMAP_HEADER_SIZE_BYTES = 4 * sizeof(uint32_t) + 2 * 256,
- };
+ static const size_t IDMAP_HEADER_SIZE_BYTES = 4 * sizeof(uint32_t) + 2 * 256;
// Retrieve idmap meta-data.
//
diff --git a/libs/androidfw/Android.mk b/libs/androidfw/Android.mk
index 20d5470..461160a 100644
--- a/libs/androidfw/Android.mk
+++ b/libs/androidfw/Android.mk
@@ -40,10 +40,12 @@
# For the host
# =====================================================
include $(CLEAR_VARS)
+LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
LOCAL_MODULE:= libandroidfw
LOCAL_MODULE_TAGS := optional
LOCAL_CFLAGS += -DSTATIC_ANDROIDFW_FOR_TOOLS
+LOCAL_CFLAGS += -Wall -Werror -Wunused -Wunreachable-code
LOCAL_SRC_FILES:= $(hostSources)
LOCAL_C_INCLUDES := external/zlib
@@ -54,6 +56,7 @@
# =====================================================
include $(CLEAR_VARS)
+LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
LOCAL_MODULE:= libandroidfw
LOCAL_MODULE_TAGS := optional
@@ -63,11 +66,13 @@
system/core/include
LOCAL_STATIC_LIBRARIES := libziparchive
LOCAL_SHARED_LIBRARIES := \
- libbinder \
- liblog \
- libcutils \
- libutils \
- libz
+ libbinder \
+ liblog \
+ libcutils \
+ libutils \
+ libz
+
+LOCAL_CFLAGS += -Wall -Werror -Wunused -Wunreachable-code
include $(BUILD_SHARED_LIBRARY)
diff --git a/libs/androidfw/Asset.cpp b/libs/androidfw/Asset.cpp
index 589211f..4b3382e 100644
--- a/libs/androidfw/Asset.cpp
+++ b/libs/androidfw/Asset.cpp
@@ -45,6 +45,8 @@
# define O_BINARY 0
#endif
+static const bool kIsDebug = false;
+
static Mutex gAssetLock;
static int32_t gCount = 0;
static Asset* gHead = NULL;
@@ -89,7 +91,9 @@
gTail->mNext = this;
gTail = this;
}
- //ALOGI("Creating Asset %p #%d\n", this, gCount);
+ if (kIsDebug) {
+ ALOGI("Creating Asset %p #%d\n", this, gCount);
+ }
}
Asset::~Asset(void)
@@ -109,7 +113,9 @@
mPrev->mNext = mNext;
}
mNext = mPrev = NULL;
- //ALOGI("Destroying Asset in %p #%d\n", this, gCount);
+ if (kIsDebug) {
+ ALOGI("Destroying Asset in %p #%d\n", this, gCount);
+ }
}
/*
diff --git a/libs/androidfw/AssetManager.cpp b/libs/androidfw/AssetManager.cpp
index de6a33cf..e5c5b10 100644
--- a/libs/androidfw/AssetManager.cpp
+++ b/libs/androidfw/AssetManager.cpp
@@ -64,6 +64,8 @@
using namespace android;
+static const bool kIsDebug = false;
+
/*
* Names for default app, locale, and vendor. We might want to change
* these to be an actual locale, e.g. always use en-US as the default.
@@ -152,15 +154,19 @@
mResources(NULL), mConfig(new ResTable_config),
mCacheMode(cacheMode), mCacheValid(false)
{
- int count = android_atomic_inc(&gCount)+1;
- //ALOGI("Creating AssetManager %p #%d\n", this, count);
+ int count = android_atomic_inc(&gCount) + 1;
+ if (kIsDebug) {
+ ALOGI("Creating AssetManager %p #%d\n", this, count);
+ }
memset(mConfig, 0, sizeof(ResTable_config));
}
AssetManager::~AssetManager(void)
{
int count = android_atomic_dec(&gCount);
- //ALOGI("Destroying AssetManager in %p #%d\n", this, count);
+ if (kIsDebug) {
+ ALOGI("Destroying AssetManager in %p #%d\n", this, count);
+ }
delete mConfig;
delete mResources;
@@ -1864,7 +1870,9 @@
: mPath(path), mZipFile(NULL), mModWhen(modWhen),
mResourceTableAsset(NULL), mResourceTable(NULL)
{
- //ALOGI("Creating SharedZip %p %s\n", this, (const char*)mPath);
+ if (kIsDebug) {
+ ALOGI("Creating SharedZip %p %s\n", this, (const char*)mPath);
+ }
ALOGV("+++ opening zip '%s'\n", mPath.string());
mZipFile = ZipFileRO::open(mPath.string());
if (mZipFile == NULL) {
@@ -1958,7 +1966,9 @@
AssetManager::SharedZip::~SharedZip()
{
- //ALOGI("Destroying SharedZip %p %s\n", this, (const char*)mPath);
+ if (kIsDebug) {
+ ALOGI("Destroying SharedZip %p %s\n", this, (const char*)mPath);
+ }
if (mResourceTable != NULL) {
delete mResourceTable;
}
diff --git a/libs/androidfw/BackupData.cpp b/libs/androidfw/BackupData.cpp
index d16d5498..ba4a4ff 100644
--- a/libs/androidfw/BackupData.cpp
+++ b/libs/androidfw/BackupData.cpp
@@ -27,7 +27,7 @@
namespace android {
-static const bool DEBUG = false;
+static const bool kIsDebug = false;
/*
* File Format (v1):
@@ -45,12 +45,6 @@
const static int ROUND_UP[4] = { 0, 3, 2, 1 };
static inline size_t
-round_up(size_t n)
-{
- return n + ROUND_UP[n % 4];
-}
-
-static inline size_t
padding_extra(size_t n)
{
return ROUND_UP[n % 4];
@@ -62,7 +56,7 @@
m_entityCount(0)
{
m_pos = (ssize_t) lseek(fd, 0, SEEK_CUR);
- if (DEBUG) ALOGI("BackupDataWriter(%d) @ %ld", fd, (long)m_pos);
+ if (kIsDebug) ALOGI("BackupDataWriter(%d) @ %ld", fd, (long)m_pos);
}
BackupDataWriter::~BackupDataWriter()
@@ -79,7 +73,7 @@
paddingSize = padding_extra(n);
if (paddingSize > 0) {
uint32_t padding = 0xbcbcbcbc;
- if (DEBUG) ALOGI("writing %zd padding bytes for %d", paddingSize, n);
+ if (kIsDebug) ALOGI("writing %zd padding bytes for %d", paddingSize, n);
amt = write(m_fd, &padding, paddingSize);
if (amt != paddingSize) {
m_status = errno;
@@ -112,7 +106,7 @@
} else {
k = key;
}
- if (DEBUG) {
+ if (kIsDebug) {
ALOGD("Writing header: prefix='%s' key='%s' dataSize=%zu", m_keyPrefix.string(),
key.string(), dataSize);
}
@@ -126,7 +120,7 @@
header.keyLen = tolel(keyLen);
header.dataSize = tolel(dataSize);
- if (DEBUG) ALOGI("writing entity header, %zu bytes", sizeof(entity_header_v1));
+ if (kIsDebug) ALOGI("writing entity header, %zu bytes", sizeof(entity_header_v1));
amt = write(m_fd, &header, sizeof(entity_header_v1));
if (amt != sizeof(entity_header_v1)) {
m_status = errno;
@@ -134,7 +128,7 @@
}
m_pos += amt;
- if (DEBUG) ALOGI("writing entity header key, %zd bytes", keyLen+1);
+ if (kIsDebug) ALOGI("writing entity header key, %zd bytes", keyLen+1);
amt = write(m_fd, k.string(), keyLen+1);
if (amt != keyLen+1) {
m_status = errno;
@@ -152,10 +146,10 @@
status_t
BackupDataWriter::WriteEntityData(const void* data, size_t size)
{
- if (DEBUG) ALOGD("Writing data: size=%lu", (unsigned long) size);
+ if (kIsDebug) ALOGD("Writing data: size=%lu", (unsigned long) size);
if (m_status != NO_ERROR) {
- if (DEBUG) {
+ if (kIsDebug) {
ALOGD("Not writing data - stream in error state %d (%s)", m_status, strerror(m_status));
}
return m_status;
@@ -167,7 +161,7 @@
ssize_t amt = write(m_fd, data, size);
if (amt != (ssize_t)size) {
m_status = errno;
- if (DEBUG) ALOGD("write returned error %d (%s)", m_status, strerror(m_status));
+ if (kIsDebug) ALOGD("write returned error %d (%s)", m_status, strerror(m_status));
return m_status;
}
m_pos += amt;
@@ -189,7 +183,7 @@
{
memset(&m_header, 0, sizeof(m_header));
m_pos = (ssize_t) lseek(fd, 0, SEEK_CUR);
- if (DEBUG) ALOGI("BackupDataReader(%d) @ %ld", fd, (long)m_pos);
+ if (kIsDebug) ALOGI("BackupDataReader(%d) @ %ld", fd, (long)m_pos);
}
BackupDataReader::~BackupDataReader()
@@ -342,15 +336,19 @@
return -1;
}
int remaining = m_dataEndPos - m_pos;
- //ALOGD("ReadEntityData size=%d m_pos=0x%x m_dataEndPos=0x%x remaining=%d\n",
- // size, m_pos, m_dataEndPos, remaining);
+ if (kIsDebug) {
+ ALOGD("ReadEntityData size=%zu m_pos=0x%zx m_dataEndPos=0x%zx remaining=%d\n",
+ size, m_pos, m_dataEndPos, remaining);
+ }
if (remaining <= 0) {
return 0;
}
if (((int)size) > remaining) {
size = remaining;
}
- //ALOGD(" reading %d bytes", size);
+ if (kIsDebug) {
+ ALOGD(" reading %zu bytes", size);
+ }
int amt = read(m_fd, data, size);
if (amt < 0) {
m_status = errno;
diff --git a/libs/androidfw/BackupHelpers.cpp b/libs/androidfw/BackupHelpers.cpp
index 52dce9f..3f82830 100644
--- a/libs/androidfw/BackupHelpers.cpp
+++ b/libs/androidfw/BackupHelpers.cpp
@@ -68,14 +68,11 @@
const static int CURRENT_METADATA_VERSION = 1;
-#if 1
-#define LOGP(f, x...)
-#else
+static const bool kIsDebug = false;
#if TEST_BACKUP_HELPERS
-#define LOGP(f, x...) printf(f "\n", x)
+#define LOGP(f, x...) if (kIsDebug) printf(f "\n", x)
#else
-#define LOGP(x...) ALOGD(x)
-#endif
+#define LOGP(x...) if (kIsDebug) ALOGD(x)
#endif
const static int ROUND_UP[4] = { 0, 3, 2, 1 };
@@ -205,13 +202,6 @@
}
static int
-write_delete_file(BackupDataWriter* dataStream, const String8& key)
-{
- LOGP("write_delete_file %s\n", key.string());
- return dataStream->WriteEntityHeader(key, -1);
-}
-
-static int
write_update_file(BackupDataWriter* dataStream, int fd, int mode, const String8& key,
char const* realFilename)
{
@@ -225,8 +215,6 @@
file_metadata_v1 metadata;
char* buf = (char*)malloc(bufsize);
- int crc = crc32(0L, Z_NULL, 0);
-
fileSize = lseek(fd, 0, SEEK_END);
lseek(fd, 0, SEEK_SET);
@@ -442,18 +430,6 @@
return 0;
}
-// Utility function, equivalent to stpcpy(): perform a strcpy, but instead of
-// returning the initial dest, return a pointer to the trailing NUL.
-static char* strcpy_ptr(char* dest, const char* str) {
- if (dest && str) {
- while ((*dest = *str) != 0) {
- dest++;
- str++;
- }
- }
- return dest;
-}
-
static void calc_tar_checksum(char* buf) {
// [ 148 : 8 ] checksum -- to be calculated with this field as space chars
memset(buf + 148, ' ', 8);
@@ -579,7 +555,7 @@
snprintf(buf + 124, 12, "%011llo", (isdir) ? 0LL : s.st_size);
// [ 136 : 12 ] last mod time as a UTC time_t
- snprintf(buf + 136, 12, "%0lo", s.st_mtime);
+ snprintf(buf + 136, 12, "%0lo", (unsigned long)s.st_mtime);
// [ 156 : 1 ] link/file type
uint8_t type;
@@ -635,7 +611,6 @@
// construct the pax extended header data block
memset(paxData, 0, BUFSIZE - (paxData - buf));
- int len;
// size header -- calc len in digits by actually rendering the number
// to a string - brute force but simple
@@ -1200,7 +1175,6 @@
size_t bufSize = strlen(str)+1;
char* buf = (char*)malloc(bufSize);
String8 string;
- int cookie = 0x11111111;
size_t actualSize;
bool done;
int type;
@@ -1333,23 +1307,12 @@
fprintf(stderr, "stat '%s' failed: %s\n", filename, strerror(errno));
return errno;
}
- times[0].tv_sec = st.st_atime;
- times[1].tv_sec = st.st_mtime;
- // If st_atime is a macro then struct stat64 uses struct timespec
- // to store the access and modif time values and typically
- // st_*time_nsec is not defined. In glibc, this is controlled by
- // __USE_MISC.
-#ifdef __USE_MISC
-#if !defined(st_atime) || defined(st_atime_nsec)
-#error "Check if this __USE_MISC conditional is still needed."
-#endif
+ times[0].tv_sec = st.st_atim.tv_sec;
times[0].tv_usec = st.st_atim.tv_nsec / 1000;
+
+ times[1].tv_sec = st.st_mtim.tv_sec;
times[1].tv_usec = st.st_mtim.tv_nsec / 1000;
-#else
- times[0].tv_usec = st.st_atime_nsec / 1000;
- times[1].tv_usec = st.st_mtime_nsec / 1000;
-#endif
return 0;
}
@@ -1490,7 +1453,6 @@
backup_helper_test_null_base()
{
int err;
- int oldSnapshotFD;
int dataStreamFD;
int newSnapshotFD;
@@ -1539,7 +1501,6 @@
backup_helper_test_missing_file()
{
int err;
- int oldSnapshotFD;
int dataStreamFD;
int newSnapshotFD;
diff --git a/libs/androidfw/ObbFile.cpp b/libs/androidfw/ObbFile.cpp
index ec59f06..195fa9a 100644
--- a/libs/androidfw/ObbFile.cpp
+++ b/libs/androidfw/ObbFile.cpp
@@ -122,7 +122,7 @@
if (fileLength < 0) {
ALOGW("error seeking in ObbFile: %s\n", strerror(errno));
} else {
- ALOGW("file is only %lld (less than %d minimum)\n", fileLength, kFooterMinSize);
+ ALOGW("file is only %lld (less than %d minimum)\n", (long long int)fileLength, kFooterMinSize);
}
return false;
}
@@ -150,8 +150,8 @@
footerSize = get4LE((unsigned char*)footer);
if (footerSize > (size_t)fileLength - kFooterTagSize
|| footerSize > kMaxBufSize) {
- ALOGW("claimed footer size is too large (0x%08zx; file size is 0x%08llx)\n",
- footerSize, fileLength);
+ ALOGW("claimed footer size is too large (0x%08zx; file size is 0x%08lld)\n",
+ footerSize, (long long int)fileLength);
return false;
}
@@ -164,7 +164,7 @@
off64_t fileOffset = fileLength - footerSize - kFooterTagSize;
if (lseek64(fd, fileOffset, SEEK_SET) != fileOffset) {
- ALOGW("seek %lld failed: %s\n", fileOffset, strerror(errno));
+ ALOGW("seek %lld failed: %s\n", (long long int)fileOffset, strerror(errno));
return false;
}
diff --git a/libs/androidfw/ResourceTypes.cpp b/libs/androidfw/ResourceTypes.cpp
index 3cf1021..acb8934 100644
--- a/libs/androidfw/ResourceTypes.cpp
+++ b/libs/androidfw/ResourceTypes.cpp
@@ -27,6 +27,10 @@
#include <utils/String16.h>
#include <utils/String8.h>
+#ifdef HAVE_ANDROID_OS
+#include <binder/TextOutput.h>
+#endif
+
#include <stdlib.h>
#include <string.h>
#include <memory.h>
@@ -38,15 +42,6 @@
#define INT32_MAX ((int32_t)(2147483647))
#endif
-#define STRING_POOL_NOISY(x) //x
-#define XML_NOISY(x) //x
-#define TABLE_NOISY(x) //x
-#define TABLE_GETENTRY(x) //x
-#define TABLE_SUPER_NOISY(x) //x
-#define LOAD_TABLE_NOISY(x) //x
-#define TABLE_THEME(x) //x
-#define LIB_NOISY(x) //x
-
namespace android {
#ifdef HAVE_WINSOCK
@@ -72,6 +67,19 @@
#define APP_PACKAGE_ID 0x7f
#define SYS_PACKAGE_ID 0x01
+static const bool kDebugStringPoolNoisy = false;
+static const bool kDebugXMLNoisy = false;
+static const bool kDebugTableNoisy = false;
+static const bool kDebugTableGetEntry = false;
+static const bool kDebugTableSuperNoisy = false;
+static const bool kDebugLoadTableNoisy = false;
+static const bool kDebugLoadTableSuperNoisy = false;
+static const bool kDebugTableTheme = false;
+static const bool kDebugResXMLTree = false;
+static const bool kDebugLibNoisy = false;
+
+// TODO: This code uses 0xFFFFFFFF converted to bag_set* as a sentinel value. This is bad practice.
+
// Standard C isspace() is only required to look at the low byte of its input, so
// produces incorrect results for UTF-16 characters. For safety's sake, assume that
// any high-byte UTF-16 code point is not whitespace.
@@ -719,12 +727,14 @@
if (mCache == NULL) {
#ifndef HAVE_ANDROID_OS
- STRING_POOL_NOISY(ALOGI("CREATING STRING CACHE OF %d bytes",
- mHeader->stringCount*sizeof(char16_t**)));
+ if (kDebugStringPoolNoisy) {
+ ALOGI("CREATING STRING CACHE OF %zu bytes",
+ mHeader->stringCount*sizeof(char16_t**));
+ }
#else
// We do not want to be in this case when actually running Android.
- ALOGW("CREATING STRING CACHE OF %d bytes",
- mHeader->stringCount*sizeof(char16_t**));
+ ALOGW("CREATING STRING CACHE OF %zu bytes",
+ static_cast<size_t>(mHeader->stringCount*sizeof(char16_t**)));
#endif
mCache = (char16_t**)calloc(mHeader->stringCount, sizeof(char16_t**));
if (mCache == NULL) {
@@ -753,7 +763,9 @@
return NULL;
}
- STRING_POOL_NOISY(ALOGI("Caching UTF8 string: %s", u8str));
+ if (kDebugStringPoolNoisy) {
+ ALOGI("Caching UTF8 string: %s", u8str);
+ }
utf8_to_utf16(u8str, u8len, u16str);
mCache[idx] = u16str;
return u16str;
@@ -843,7 +855,9 @@
size_t len;
if ((mHeader->flags&ResStringPool_header::UTF8_FLAG) != 0) {
- STRING_POOL_NOISY(ALOGI("indexOfString UTF-8: %s", String8(str, strLen).string()));
+ if (kDebugStringPoolNoisy) {
+ ALOGI("indexOfString UTF-8: %s", String8(str, strLen).string());
+ }
// The string pool contains UTF 8 strings; we don't want to cause
// temporary UTF-16 strings to be created as we search.
@@ -869,10 +883,14 @@
} else {
c = -1;
}
- STRING_POOL_NOISY(ALOGI("Looking at %s, cmp=%d, l/mid/h=%d/%d/%d\n",
- (const char*)s, c, (int)l, (int)mid, (int)h));
+ if (kDebugStringPoolNoisy) {
+ ALOGI("Looking at %s, cmp=%d, l/mid/h=%d/%d/%d\n",
+ (const char*)s, c, (int)l, (int)mid, (int)h);
+ }
if (c == 0) {
- STRING_POOL_NOISY(ALOGI("MATCH!"));
+ if (kDebugStringPoolNoisy) {
+ ALOGI("MATCH!");
+ }
free(convBuffer);
return mid;
} else if (c < 0) {
@@ -891,18 +909,22 @@
const size_t str8Len = str8.size();
for (int i=mHeader->stringCount-1; i>=0; i--) {
const char* s = string8At(i, &len);
- STRING_POOL_NOISY(ALOGI("Looking at %s, i=%d\n",
- String8(s).string(),
- i));
+ if (kDebugStringPoolNoisy) {
+ ALOGI("Looking at %s, i=%d\n", String8(s).string(), i);
+ }
if (s && str8Len == len && memcmp(s, str8.string(), str8Len) == 0) {
- STRING_POOL_NOISY(ALOGI("MATCH!"));
+ if (kDebugStringPoolNoisy) {
+ ALOGI("MATCH!");
+ }
return i;
}
}
}
} else {
- STRING_POOL_NOISY(ALOGI("indexOfString UTF-16: %s", String8(str, strLen).string()));
+ if (kDebugStringPoolNoisy) {
+ ALOGI("indexOfString UTF-16: %s", String8(str, strLen).string());
+ }
if (mHeader->flags&ResStringPool_header::SORTED_FLAG) {
// Do a binary search for the string...
@@ -914,11 +936,14 @@
mid = l + (h - l)/2;
const char16_t* s = stringAt(mid, &len);
int c = s ? strzcmp16(s, len, str, strLen) : -1;
- STRING_POOL_NOISY(ALOGI("Looking at %s, cmp=%d, l/mid/h=%d/%d/%d\n",
- String8(s).string(),
- c, (int)l, (int)mid, (int)h));
+ if (kDebugStringPoolNoisy) {
+ ALOGI("Looking at %s, cmp=%d, l/mid/h=%d/%d/%d\n",
+ String8(s).string(), c, (int)l, (int)mid, (int)h);
+ }
if (c == 0) {
- STRING_POOL_NOISY(ALOGI("MATCH!"));
+ if (kDebugStringPoolNoisy) {
+ ALOGI("MATCH!");
+ }
return mid;
} else if (c < 0) {
l = mid + 1;
@@ -933,11 +958,13 @@
// block, start searching at the back.
for (int i=mHeader->stringCount-1; i>=0; i--) {
const char16_t* s = stringAt(i, &len);
- STRING_POOL_NOISY(ALOGI("Looking at %s, i=%d\n",
- String8(s).string(),
- i));
+ if (kDebugStringPoolNoisy) {
+ ALOGI("Looking at %s, i=%d\n", String8(s).string(), i);
+ }
if (s && strLen == len && strzcmp16(s, len, str, strLen) == 0) {
- STRING_POOL_NOISY(ALOGI("MATCH!"));
+ if (kDebugStringPoolNoisy) {
+ ALOGI("MATCH!");
+ }
return i;
}
}
@@ -1138,7 +1165,9 @@
{
int32_t id = getAttributeNamespaceID(idx);
//printf("attribute namespace=%d idx=%d event=%p\n", id, idx, mEventCode);
- //XML_NOISY(printf("getAttributeNamespace 0x%x=0x%x\n", idx, id));
+ if (kDebugXMLNoisy) {
+ printf("getAttributeNamespace 0x%zx=0x%x\n", idx, id);
+ }
return id >= 0 ? mTree.mStrings.stringAt(id, outLen) : NULL;
}
@@ -1146,7 +1175,9 @@
{
int32_t id = getAttributeNamespaceID(idx);
//printf("attribute namespace=%d idx=%d event=%p\n", id, idx, mEventCode);
- //XML_NOISY(printf("getAttributeNamespace 0x%x=0x%x\n", idx, id));
+ if (kDebugXMLNoisy) {
+ printf("getAttributeNamespace 0x%zx=0x%x\n", idx, id);
+ }
return id >= 0 ? mTree.mStrings.string8At(id, outLen) : NULL;
}
@@ -1169,7 +1200,9 @@
{
int32_t id = getAttributeNameID(idx);
//printf("attribute name=%d idx=%d event=%p\n", id, idx, mEventCode);
- //XML_NOISY(printf("getAttributeName 0x%x=0x%x\n", idx, id));
+ if (kDebugXMLNoisy) {
+ printf("getAttributeName 0x%zx=0x%x\n", idx, id);
+ }
return id >= 0 ? mTree.mStrings.stringAt(id, outLen) : NULL;
}
@@ -1177,7 +1210,9 @@
{
int32_t id = getAttributeNameID(idx);
//printf("attribute name=%d idx=%d event=%p\n", id, idx, mEventCode);
- //XML_NOISY(printf("getAttributeName 0x%x=0x%x\n", idx, id));
+ if (kDebugXMLNoisy) {
+ printf("getAttributeName 0x%zx=0x%x\n", idx, id);
+ }
return id >= 0 ? mTree.mStrings.string8At(id, outLen) : NULL;
}
@@ -1208,7 +1243,9 @@
const char16_t* ResXMLParser::getAttributeStringValue(size_t idx, size_t* outLen) const
{
int32_t id = getAttributeValueStringID(idx);
- //XML_NOISY(printf("getAttributeValue 0x%x=0x%x\n", idx, id));
+ if (kDebugXMLNoisy) {
+ printf("getAttributeValue 0x%zx=0x%x\n", idx, id);
+ }
return id >= 0 ? mTree.mStrings.stringAt(id, outLen) : NULL;
}
@@ -1299,54 +1336,69 @@
ns8 = String8(ns, nsLen);
}
attr8 = String8(attr, attrLen);
- STRING_POOL_NOISY(ALOGI("indexOfAttribute UTF8 %s (%d) / %s (%d)", ns8.string(), nsLen,
- attr8.string(), attrLen));
+ if (kDebugStringPoolNoisy) {
+ ALOGI("indexOfAttribute UTF8 %s (%zu) / %s (%zu)", ns8.string(), nsLen,
+ attr8.string(), attrLen);
+ }
for (size_t i=0; i<N; i++) {
size_t curNsLen = 0, curAttrLen = 0;
const char* curNs = getAttributeNamespace8(i, &curNsLen);
const char* curAttr = getAttributeName8(i, &curAttrLen);
- STRING_POOL_NOISY(ALOGI(" curNs=%s (%d), curAttr=%s (%d)", curNs, curNsLen,
- curAttr, curAttrLen));
+ if (kDebugStringPoolNoisy) {
+ ALOGI(" curNs=%s (%zu), curAttr=%s (%zu)", curNs, curNsLen, curAttr, curAttrLen);
+ }
if (curAttr != NULL && curNsLen == nsLen && curAttrLen == attrLen
&& memcmp(attr8.string(), curAttr, attrLen) == 0) {
if (ns == NULL) {
if (curNs == NULL) {
- STRING_POOL_NOISY(ALOGI(" FOUND!"));
+ if (kDebugStringPoolNoisy) {
+ ALOGI(" FOUND!");
+ }
return i;
}
} else if (curNs != NULL) {
//printf(" --> ns=%s, curNs=%s\n",
// String8(ns).string(), String8(curNs).string());
if (memcmp(ns8.string(), curNs, nsLen) == 0) {
- STRING_POOL_NOISY(ALOGI(" FOUND!"));
+ if (kDebugStringPoolNoisy) {
+ ALOGI(" FOUND!");
+ }
return i;
}
}
}
}
} else {
- STRING_POOL_NOISY(ALOGI("indexOfAttribute UTF16 %s (%d) / %s (%d)",
- String8(ns, nsLen).string(), nsLen,
- String8(attr, attrLen).string(), attrLen));
+ if (kDebugStringPoolNoisy) {
+ ALOGI("indexOfAttribute UTF16 %s (%zu) / %s (%zu)",
+ String8(ns, nsLen).string(), nsLen,
+ String8(attr, attrLen).string(), attrLen);
+ }
for (size_t i=0; i<N; i++) {
size_t curNsLen = 0, curAttrLen = 0;
const char16_t* curNs = getAttributeNamespace(i, &curNsLen);
const char16_t* curAttr = getAttributeName(i, &curAttrLen);
- STRING_POOL_NOISY(ALOGI(" curNs=%s (%d), curAttr=%s (%d)",
- String8(curNs, curNsLen).string(), curNsLen,
- String8(curAttr, curAttrLen).string(), curAttrLen));
+ if (kDebugStringPoolNoisy) {
+ ALOGI(" curNs=%s (%zu), curAttr=%s (%zu)",
+ String8(curNs, curNsLen).string(), curNsLen,
+ String8(curAttr, curAttrLen).string(), curAttrLen);
+ }
if (curAttr != NULL && curNsLen == nsLen && curAttrLen == attrLen
&& (memcmp(attr, curAttr, attrLen*sizeof(char16_t)) == 0)) {
if (ns == NULL) {
if (curNs == NULL) {
- STRING_POOL_NOISY(ALOGI(" FOUND!"));
+ if (kDebugStringPoolNoisy) {
+ ALOGI(" FOUND!");
+ }
return i;
}
} else if (curNs != NULL) {
//printf(" --> ns=%s, curNs=%s\n",
// String8(ns).string(), String8(curNs).string());
if (memcmp(ns, curNs, nsLen*sizeof(char16_t)) == 0) {
- STRING_POOL_NOISY(ALOGI(" FOUND!"));
+ if (kDebugStringPoolNoisy) {
+ ALOGI(" FOUND!");
+ }
return i;
}
}
@@ -1394,7 +1446,9 @@
do {
const ResXMLTree_node* next = (const ResXMLTree_node*)
(((const uint8_t*)mCurNode) + dtohl(mCurNode->header.size));
- //ALOGW("Next node: prev=%p, next=%p\n", mCurNode, next);
+ if (kDebugXMLNoisy) {
+ ALOGI("Next node: prev=%p, next=%p\n", mCurNode, next);
+ }
if (((const uint8_t*)next) >= mTree.mDataEnd) {
mCurNode = NULL;
@@ -1471,7 +1525,9 @@
, mDynamicRefTable(dynamicRefTable)
, mError(NO_INIT), mOwnedData(NULL)
{
- //ALOGI("Creating ResXMLTree %p #%d\n", this, android_atomic_inc(&gCount)+1);
+ if (kDebugResXMLTree) {
+ ALOGI("Creating ResXMLTree %p #%d\n", this, android_atomic_inc(&gCount)+1);
+ }
restart();
}
@@ -1480,13 +1536,17 @@
, mDynamicRefTable(NULL)
, mError(NO_INIT), mOwnedData(NULL)
{
- //ALOGI("Creating ResXMLTree %p #%d\n", this, android_atomic_inc(&gCount)+1);
+ if (kDebugResXMLTree) {
+ ALOGI("Creating ResXMLTree %p #%d\n", this, android_atomic_inc(&gCount)+1);
+ }
restart();
}
ResXMLTree::~ResXMLTree()
{
- //ALOGI("Destroying ResXMLTree in %p #%d\n", this, android_atomic_dec(&gCount)-1);
+ if (kDebugResXMLTree) {
+ ALOGI("Destroying ResXMLTree in %p #%d\n", this, android_atomic_dec(&gCount)-1);
+ }
uninit();
}
@@ -1539,8 +1599,10 @@
}
const uint16_t type = dtohs(chunk->type);
const size_t size = dtohl(chunk->size);
- XML_NOISY(printf("Scanning @ %p: type=0x%x, size=0x%x\n",
- (void*)(((uint32_t)chunk)-((uint32_t)mHeader)), type, size));
+ if (kDebugXMLNoisy) {
+ printf("Scanning @ %p: type=0x%x, size=0x%zx\n",
+ (void*)(((uintptr_t)chunk)-((uintptr_t)mHeader)), type, size);
+ }
if (type == RES_STRING_POOL_TYPE) {
mStrings.setTo(chunk, size);
} else if (type == RES_XML_RESOURCE_MAP_TYPE) {
@@ -1563,7 +1625,9 @@
mRootCode = mEventCode;
break;
} else {
- XML_NOISY(printf("Skipping unknown chunk!\n"));
+ if (kDebugXMLNoisy) {
+ printf("Skipping unknown chunk!\n");
+ }
}
lastChunk = chunk;
chunk = (const ResChunk_header*)
@@ -2147,9 +2211,11 @@
myDelta += requested->screenHeightDp - screenHeightDp;
otherDelta += requested->screenHeightDp - o.screenHeightDp;
}
- //ALOGI("Comparing this %dx%d to other %dx%d in %dx%d: myDelta=%d otherDelta=%d",
- // screenWidthDp, screenHeightDp, o.screenWidthDp, o.screenHeightDp,
- // requested->screenWidthDp, requested->screenHeightDp, myDelta, otherDelta);
+ if (kDebugTableSuperNoisy) {
+ ALOGI("Comparing this %dx%d to other %dx%d in %dx%d: myDelta=%d otherDelta=%d",
+ screenWidthDp, screenHeightDp, o.screenWidthDp, o.screenHeightDp,
+ requested->screenWidthDp, requested->screenHeightDp, myDelta, otherDelta);
+ }
if (myDelta != otherDelta) {
return myDelta < otherDelta;
}
@@ -2404,11 +2470,17 @@
}
if (screenSizeDp != 0) {
if (screenWidthDp != 0 && screenWidthDp > settings.screenWidthDp) {
- //ALOGI("Filtering out width %d in requested %d", screenWidthDp, settings.screenWidthDp);
+ if (kDebugTableSuperNoisy) {
+ ALOGI("Filtering out width %d in requested %d", screenWidthDp,
+ settings.screenWidthDp);
+ }
return false;
}
if (screenHeightDp != 0 && screenHeightDp > settings.screenHeightDp) {
- //ALOGI("Filtering out height %d in requested %d", screenHeightDp, settings.screenHeightDp);
+ if (kDebugTableSuperNoisy) {
+ ALOGI("Filtering out height %d in requested %d", screenHeightDp,
+ settings.screenHeightDp);
+ }
return false;
}
}
@@ -2428,9 +2500,13 @@
// For compatibility, we count a request for KEYSHIDDEN_NO as also
// matching the more recent KEYSHIDDEN_SOFT. Basically
// KEYSHIDDEN_NO means there is some kind of keyboard available.
- //ALOGI("Matching keysHidden: have=%d, config=%d\n", keysHidden, setKeysHidden);
+ if (kDebugTableSuperNoisy) {
+ ALOGI("Matching keysHidden: have=%d, config=%d\n", keysHidden, setKeysHidden);
+ }
if (keysHidden != KEYSHIDDEN_NO || setKeysHidden != KEYSHIDDEN_SOFT) {
- //ALOGI("No match!");
+ if (kDebugTableSuperNoisy) {
+ ALOGI("No match!");
+ }
return false;
}
}
@@ -2935,17 +3011,25 @@
void clearBagCache() {
if (bags) {
- TABLE_NOISY(printf("bags=%p\n", bags));
+ if (kDebugTableNoisy) {
+ printf("bags=%p\n", bags);
+ }
for (size_t i = 0; i < bags->size(); i++) {
- TABLE_NOISY(printf("type=%d\n", i));
+ if (kDebugTableNoisy) {
+ printf("type=%zu\n", i);
+ }
const TypeList& typeList = types[i];
if (!typeList.isEmpty()) {
bag_set** typeBags = bags->get(i);
- TABLE_NOISY(printf("typeBags=%p\n", typeBags));
+ if (kDebugTableNoisy) {
+ printf("typeBags=%p\n", typeBags);
+ }
if (typeBags) {
const size_t N = typeList[0]->entryCount;
- TABLE_NOISY(printf("type->entryCount=%x\n", N));
- for (size_t j=0; j<N; j++) {
+ if (kDebugTableNoisy) {
+ printf("type->entryCount=%zu\n", N);
+ }
+ for (size_t j = 0; j < N; j++) {
if (typeBags[j] && typeBags[j] != (bag_set*)0xFFFFFFFF)
free(typeBags[j]);
}
@@ -3053,7 +3137,9 @@
uint32_t bagTypeSpecFlags = 0;
mTable.lock();
const ssize_t N = mTable.getBagLocked(resID, &bag, &bagTypeSpecFlags);
- TABLE_NOISY(ALOGV("Applying style 0x%08x to theme %p, count=%d", resID, this, N));
+ if (kDebugTableNoisy) {
+ ALOGV("Applying style 0x%08x to theme %p, count=%zu", resID, this, N);
+ }
if (N < 0) {
mTable.unlock();
return N;
@@ -3084,7 +3170,6 @@
curPackageIndex = pidx;
curPI = mPackages[pidx];
if (curPI == NULL) {
- PackageGroup* const grp = mTable.mPackageGroups[pidx];
curPI = (package_info*)malloc(sizeof(package_info));
memset(curPI, 0, sizeof(*curPI));
mPackages[pidx] = curPI;
@@ -3116,9 +3201,11 @@
continue;
}
theme_entry* curEntry = curEntries + e;
- TABLE_NOISY(ALOGV("Attr 0x%08x: type=0x%x, data=0x%08x; curType=0x%x",
- attrRes, bag->map.value.dataType, bag->map.value.data,
- curEntry->value.dataType));
+ if (kDebugTableNoisy) {
+ ALOGV("Attr 0x%08x: type=0x%x, data=0x%08x; curType=0x%x",
+ attrRes, bag->map.value.dataType, bag->map.value.data,
+ curEntry->value.dataType);
+ }
if (force || curEntry->value.dataType == Res_value::TYPE_NULL) {
curEntry->stringBlock = bag->stringBlock;
curEntry->typeSpecFlags |= bagTypeSpecFlags;
@@ -3130,17 +3217,21 @@
mTable.unlock();
- //ALOGI("Applying style 0x%08x (force=%d) theme %p...\n", resID, force, this);
- //dumpToLog();
+ if (kDebugTableTheme) {
+ ALOGI("Applying style 0x%08x (force=%d) theme %p...\n", resID, force, this);
+ dumpToLog();
+ }
return NO_ERROR;
}
status_t ResTable::Theme::setTo(const Theme& other)
{
- //ALOGI("Setting theme %p from theme %p...\n", this, &other);
- //dumpToLog();
- //other.dumpToLog();
+ if (kDebugTableTheme) {
+ ALOGI("Setting theme %p from theme %p...\n", this, &other);
+ dumpToLog();
+ other.dumpToLog();
+ }
if (&mTable == &other.mTable) {
for (size_t i=0; i<Res_MAXPACKAGE; i++) {
@@ -3169,8 +3260,10 @@
}
}
- //ALOGI("Final theme:");
- //dumpToLog();
+ if (kDebugTableTheme) {
+ ALOGI("Final theme:");
+ dumpToLog();
+ }
return NO_ERROR;
}
@@ -3187,23 +3280,33 @@
const uint32_t t = Res_GETTYPE(resID);
const uint32_t e = Res_GETENTRY(resID);
- TABLE_THEME(ALOGI("Looking up attr 0x%08x in theme %p", resID, this));
+ if (kDebugTableTheme) {
+ ALOGI("Looking up attr 0x%08x in theme %p", resID, this);
+ }
if (p >= 0) {
const package_info* const pi = mPackages[p];
- TABLE_THEME(ALOGI("Found package: %p", pi));
+ if (kDebugTableTheme) {
+ ALOGI("Found package: %p", pi);
+ }
if (pi != NULL) {
- TABLE_THEME(ALOGI("Desired type index is %ld in avail %d", t, Res_MAXTYPE + 1));
+ if (kDebugTableTheme) {
+ ALOGI("Desired type index is %zd in avail %zu", t, Res_MAXTYPE + 1);
+ }
if (t <= Res_MAXTYPE) {
const type_info& ti = pi->types[t];
- TABLE_THEME(ALOGI("Desired entry index is %ld in avail %d", e, ti.numEntries));
+ if (kDebugTableTheme) {
+ ALOGI("Desired entry index is %u in avail %zu", e, ti.numEntries);
+ }
if (e < ti.numEntries) {
const theme_entry& te = ti.entries[e];
if (outTypeSpecFlags != NULL) {
*outTypeSpecFlags |= te.typeSpecFlags;
}
- TABLE_THEME(ALOGI("Theme value: type=0x%x, data=0x%08x",
- te.value.dataType, te.value.data));
+ if (kDebugTableTheme) {
+ ALOGI("Theme value: type=0x%x, data=0x%08x",
+ te.value.dataType, te.value.data);
+ }
const uint8_t type = te.value.dataType;
if (type == Res_value::TYPE_ATTRIBUTE) {
if (cnt > 0) {
@@ -3237,8 +3340,10 @@
if (inOutValue->dataType == Res_value::TYPE_ATTRIBUTE) {
uint32_t newTypeSpecFlags;
blockIndex = getAttribute(inOutValue->data, inOutValue, &newTypeSpecFlags);
- TABLE_THEME(ALOGI("Resolving attr reference: blockIndex=%d, type=0x%x, data=%p\n",
- (int)blockIndex, (int)inOutValue->dataType, (void*)inOutValue->data));
+ if (kDebugTableTheme) {
+ ALOGI("Resolving attr reference: blockIndex=%d, type=0x%x, data=0x%x\n",
+ (int)blockIndex, (int)inOutValue->dataType, inOutValue->data);
+ }
if (inoutTypeSpecFlags != NULL) *inoutTypeSpecFlags |= newTypeSpecFlags;
//printf("Retrieved attribute new type=0x%x\n", inOutValue->dataType);
if (blockIndex < 0) {
@@ -3277,7 +3382,9 @@
{
memset(&mParams, 0, sizeof(mParams));
memset(mPackageMap, 0, sizeof(mPackageMap));
- //ALOGI("Creating ResTable %p\n", this);
+ if (kDebugTableSuperNoisy) {
+ ALOGI("Creating ResTable %p\n", this);
+ }
}
ResTable::ResTable(const void* data, size_t size, const int32_t cookie, bool copyData)
@@ -3287,12 +3394,16 @@
memset(mPackageMap, 0, sizeof(mPackageMap));
addInternal(data, size, NULL, 0, cookie, copyData);
LOG_FATAL_IF(mError != NO_ERROR, "Error parsing resource table");
- //ALOGI("Creating ResTable %p\n", this);
+ if (kDebugTableSuperNoisy) {
+ ALOGI("Creating ResTable %p\n", this);
+ }
}
ResTable::~ResTable()
{
- //ALOGI("Destroying ResTable in %p\n", this);
+ if (kDebugTableSuperNoisy) {
+ ALOGI("Destroying ResTable in %p\n", this);
+ }
uninit();
}
@@ -3421,9 +3532,10 @@
const bool notDeviceEndian = htods(0xf0) != 0xf0;
- LOAD_TABLE_NOISY(
- ALOGV("Adding resources to ResTable: data=%p, size=0x%x, cookie=%d, copy=%d "
- "idmap=%p\n", data, dataSize, cookie, copyData, idmap));
+ if (kDebugLoadTableNoisy) {
+ ALOGV("Adding resources to ResTable: data=%p, size=%zu, cookie=%d, copy=%d "
+ "idmap=%p\n", data, dataSize, cookie, copyData, idmapData);
+ }
if (copyData || notDeviceEndian) {
header->ownedData = malloc(dataSize);
@@ -3436,9 +3548,13 @@
header->header = (const ResTable_header*)data;
header->size = dtohl(header->header->header.size);
- //ALOGI("Got size 0x%x, again size 0x%x, raw size 0x%x\n", header->size,
- // dtohl(header->header->header.size), header->header->header.size);
- LOAD_TABLE_NOISY(ALOGV("Loading ResTable @%p:\n", header->header));
+ if (kDebugLoadTableSuperNoisy) {
+ ALOGI("Got size %zu, again size 0x%x, raw size 0x%x\n", header->size,
+ dtohl(header->header->header.size), header->header->header.size);
+ }
+ if (kDebugLoadTableNoisy) {
+ ALOGV("Loading ResTable @%p:\n", header->header);
+ }
if (dtohs(header->header->header.headerSize) > header->size
|| header->size > dataSize) {
ALOGW("Bad resource table: header size 0x%x or total size 0x%x is larger than data size 0x%x\n",
@@ -3466,9 +3582,11 @@
if (err != NO_ERROR) {
return (mError=err);
}
- TABLE_NOISY(ALOGV("Chunk: type=0x%x, headerSize=0x%x, size=0x%x, pos=%p\n",
- dtohs(chunk->type), dtohs(chunk->headerSize), dtohl(chunk->size),
- (void*)(((const uint8_t*)chunk) - ((const uint8_t*)header->header))));
+ if (kDebugTableNoisy) {
+ ALOGV("Chunk: type=0x%x, headerSize=0x%x, size=0x%x, pos=%p\n",
+ dtohs(chunk->type), dtohs(chunk->headerSize), dtohl(chunk->size),
+ (void*)(((const uint8_t*)chunk) - ((const uint8_t*)header->header)));
+ }
const size_t csize = dtohl(chunk->size);
const uint16_t ctype = dtohs(chunk->type);
if (ctype == RES_STRING_POOL_TYPE) {
@@ -3512,7 +3630,9 @@
ALOGW("No string values found in resource table!");
}
- TABLE_NOISY(ALOGV("Returning from add with mError=%d\n", mError));
+ if (kDebugTableNoisy) {
+ ALOGV("Returning from add with mError=%d\n", mError);
+ }
return mError;
}
@@ -3678,15 +3798,16 @@
return BAD_VALUE;
}
- TABLE_NOISY(size_t len;
- printf("Found value: pkg=%d, type=%d, str=%s, int=%d\n",
- entry.package->header->index,
- outValue->dataType,
- outValue->dataType == Res_value::TYPE_STRING
- ? String8(entry.package->header->values.stringAt(
- outValue->data, &len)).string()
- : "",
- outValue->data));
+ if (kDebugTableNoisy) {
+ size_t len;
+ printf("Found value: pkg=%zu, type=%d, str=%s, int=%d\n",
+ entry.package->header->index,
+ outValue->dataType,
+ outValue->dataType == Res_value::TYPE_STRING ?
+ String8(entry.package->header->values.stringAt(outValue->data, &len)).string() :
+ "",
+ outValue->data);
+ }
if (outSpecFlags != NULL) {
*outSpecFlags = entry.specFlags;
@@ -3707,15 +3828,16 @@
while (blockIndex >= 0 && value->dataType == Res_value::TYPE_REFERENCE
&& value->data != 0 && count < 20) {
if (outLastRef) *outLastRef = value->data;
- uint32_t lastRef = value->data;
uint32_t newFlags = 0;
const ssize_t newIndex = getResource(value->data, value, true, 0, &newFlags,
outConfig);
if (newIndex == BAD_INDEX) {
return BAD_INDEX;
}
- TABLE_THEME(ALOGI("Resolving reference %p: newIndex=%d, type=0x%x, data=%p\n",
- (void*)lastRef, (int)newIndex, (int)value->dataType, (void*)value->data));
+ if (kDebugTableTheme) {
+ ALOGI("Resolving reference 0x%x: newIndex=%d, type=0x%x, data=0x%x\n",
+ value->data, (int)newIndex, (int)value->dataType, value->data);
+ }
//printf("Getting reference 0x%08x: newIndex=%d\n", value->data, newIndex);
if (inoutTypeSpecFlags != NULL) *inoutTypeSpecFlags |= newFlags;
if (newIndex < 0) {
@@ -3822,7 +3944,9 @@
*outTypeSpecFlags = set->typeSpecFlags;
}
*outBag = (bag_entry*)(set+1);
- //ALOGI("Found existing bag for: %p\n", (void*)resID);
+ if (kDebugTableSuperNoisy) {
+ ALOGI("Found existing bag for: 0x%x\n", resID);
+ }
return set->numAttrs;
}
ALOGW("Attempt to retrieve bag 0x%08x which is invalid or in a cycle.",
@@ -3848,7 +3972,9 @@
// Mark that we are currently working on this one.
typeSet[e] = (bag_set*)0xFFFFFFFF;
- TABLE_NOISY(ALOGI("Building bag: %p\n", (void*)resID));
+ if (kDebugTableNoisy) {
+ ALOGI("Building bag: %x\n", resID);
+ }
// Now collect all bag attributes
Entry entry;
@@ -3865,13 +3991,13 @@
size_t N = count;
- TABLE_NOISY(ALOGI("Found map: size=%p parent=%p count=%d\n",
- entrySize, parent, count));
+ if (kDebugTableNoisy) {
+ ALOGI("Found map: size=%x parent=%x count=%d\n", entrySize, parent, count);
// If this map inherits from another, we need to start
// with its parent's values. Otherwise start out empty.
- TABLE_NOISY(printf("Creating new bag, entrySize=0x%08x, parent=0x%08x\n",
- entrySize, parent));
+ ALOGI("Creating new bag, entrySize=0x%08x, parent=0x%08x\n", entrySize, parent);
+ }
// This is what we are building.
bag_set* set = NULL;
@@ -3900,9 +4026,13 @@
if (NP > 0) {
memcpy(set+1, parentBag, NP*sizeof(bag_entry));
set->numAttrs = NP;
- TABLE_NOISY(ALOGI("Initialized new bag with %d inherited attributes.\n", NP));
+ if (kDebugTableNoisy) {
+ ALOGI("Initialized new bag with %zd inherited attributes.\n", NP);
+ }
} else {
- TABLE_NOISY(ALOGI("Initialized new bag with no inherited attributes.\n"));
+ if (kDebugTableNoisy) {
+ ALOGI("Initialized new bag with no inherited attributes.\n");
+ }
set->numAttrs = 0;
}
set->availAttrs = NT;
@@ -3926,10 +4056,13 @@
bag_entry* entries = (bag_entry*)(set+1);
size_t curEntry = 0;
uint32_t pos = 0;
- TABLE_NOISY(ALOGI("Starting with set %p, entries=%p, avail=%d\n",
- set, entries, set->availAttrs));
+ if (kDebugTableNoisy) {
+ ALOGI("Starting with set %p, entries=%p, avail=%zu\n", set, entries, set->availAttrs);
+ }
while (pos < count) {
- TABLE_NOISY(printf("Now at %p\n", (void*)curOff));
+ if (kDebugTableNoisy) {
+ ALOGI("Now at %p\n", (void*)curOff);
+ }
if (curOff > (dtohl(entry.type->header.size)-sizeof(ResTable_map))) {
ALOGW("ResTable_map at %d is beyond type chunk data %d",
@@ -3954,8 +4087,10 @@
uint32_t oldName = 0;
while ((isInside=(curEntry < set->numAttrs))
&& (oldName=entries[curEntry].map.name.ident) < newName) {
- TABLE_NOISY(printf("#%d: Keeping existing attribute: 0x%08x\n",
- curEntry, entries[curEntry].map.name.ident));
+ if (kDebugTableNoisy) {
+ ALOGI("#%zu: Keeping existing attribute: 0x%08x\n",
+ curEntry, entries[curEntry].map.name.ident);
+ }
curEntry++;
}
@@ -3972,8 +4107,10 @@
}
set->availAttrs = newAvail;
entries = (bag_entry*)(set+1);
- TABLE_NOISY(printf("Reallocated set %p, entries=%p, avail=%d\n",
- set, entries, set->availAttrs));
+ if (kDebugTableNoisy) {
+ ALOGI("Reallocated set %p, entries=%p, avail=%zu\n",
+ set, entries, set->availAttrs);
+ }
}
if (isInside) {
// Going in the middle, need to make space.
@@ -3981,11 +4118,13 @@
sizeof(bag_entry)*(set->numAttrs-curEntry));
set->numAttrs++;
}
- TABLE_NOISY(printf("#%d: Inserting new attribute: 0x%08x\n",
- curEntry, newName));
+ if (kDebugTableNoisy) {
+ ALOGI("#%zu: Inserting new attribute: 0x%08x\n", curEntry, newName);
+ }
} else {
- TABLE_NOISY(printf("#%d: Replacing existing attribute: 0x%08x\n",
- curEntry, oldName));
+ if (kDebugTableNoisy) {
+ ALOGI("#%zu: Replacing existing attribute: 0x%08x\n", curEntry, oldName);
+ }
}
bag_entry* cur = entries+curEntry;
@@ -3999,9 +4138,11 @@
return UNKNOWN_ERROR;
}
- TABLE_NOISY(printf("Setting entry #%d %p: block=%d, name=0x%08x, type=%d, data=0x%08x\n",
- curEntry, cur, cur->stringBlock, cur->map.name.ident,
- cur->map.value.dataType, cur->map.value.data));
+ if (kDebugTableNoisy) {
+ ALOGI("Setting entry #%zu %p: block=%zd, name=0x%08d, type=%d, data=0x%08x\n",
+ curEntry, cur, cur->stringBlock, cur->map.name.ident,
+ cur->map.value.dataType, cur->map.value.data);
+ }
// On to the next!
curEntry++;
@@ -4021,7 +4162,9 @@
*outTypeSpecFlags = set->typeSpecFlags;
}
*outBag = (bag_entry*)(set+1);
- TABLE_NOISY(ALOGI("Returning %d attrs\n", set->numAttrs));
+ if (kDebugTableNoisy) {
+ ALOGI("Returning %zu attrs\n", set->numAttrs);
+ }
return set->numAttrs;
}
return BAD_INDEX;
@@ -4030,10 +4173,14 @@
void ResTable::setParameters(const ResTable_config* params)
{
mLock.lock();
- TABLE_GETENTRY(ALOGI("Setting parameters: %s\n", params->toString().string()));
+ if (kDebugTableGetEntry) {
+ ALOGI("Setting parameters: %s\n", params->toString().string());
+ }
mParams = *params;
for (size_t i=0; i<mPackageGroups.size(); i++) {
- TABLE_NOISY(ALOGI("CLEARING BAGS FOR GROUP %d!", i));
+ if (kDebugTableNoisy) {
+ ALOGI("CLEARING BAGS FOR GROUP %zu!", i);
+ }
mPackageGroups[i]->clearBagCache();
}
mLock.unlock();
@@ -4071,7 +4218,9 @@
size_t packageLen,
uint32_t* outTypeSpecFlags) const
{
- TABLE_SUPER_NOISY(printf("Identifier for name: error=%d\n", mError));
+ if (kDebugTableSuperNoisy) {
+ printf("Identifier for name: error=%d\n", mError);
+ }
// Check for internal resource identifier as the very first thing, so
// that we will always find them even when there are no resources.
@@ -4164,10 +4313,12 @@
}
nameLen = nameEnd-name;
- TABLE_NOISY(printf("Looking for identifier: type=%s, name=%s, package=%s\n",
- String8(type, typeLen).string(),
- String8(name, nameLen).string(),
- String8(package, packageLen).string()));
+ if (kDebugTableNoisy) {
+ printf("Looking for identifier: type=%s, name=%s, package=%s\n",
+ String8(type, typeLen).string(),
+ String8(name, nameLen).string(),
+ String8(package, packageLen).string());
+ }
const size_t NG = mPackageGroups.size();
for (size_t ig=0; ig<NG; ig++) {
@@ -4175,7 +4326,9 @@
if (strzcmp16(package, packageLen,
group->name.string(), group->name.size())) {
- TABLE_NOISY(printf("Skipping package group: %s\n", String8(group->name).string()));
+ if (kDebugTableNoisy) {
+ printf("Skipping package group: %s\n", String8(group->name).string());
+ }
continue;
}
@@ -4190,8 +4343,10 @@
const TypeList& typeList = group->types[ti];
if (typeList.isEmpty()) {
- TABLE_NOISY(printf("Expected type structure not found in package %s for index %d\n",
- String8(group->name).string(), ti));
+ if (kDebugTableNoisy) {
+ ALOGI("Expected type structure not found in package %s for index %zd\n",
+ String8(group->name).string(), ti);
+ }
continue;
}
@@ -4480,7 +4635,7 @@
if (len > 0) {
return false;
}
- if (buf[0] < '0' && buf[0] > '9' && buf[0] != '.') {
+ if ((buf[0] < '0' || buf[0] > '9') && buf[0] != '.' && buf[0] != '-' && buf[0] != '+') {
return false;
}
@@ -4697,9 +4852,11 @@
rid = Res_MAKEID(
accessor->getRemappedPackage(Res_GETPACKAGE(rid)),
Res_GETTYPE(rid), Res_GETENTRY(rid));
- TABLE_NOISY(printf("Incl %s:%s/%s: 0x%08x\n",
- String8(package).string(), String8(type).string(),
- String8(name).string(), rid));
+ if (kDebugTableNoisy) {
+ ALOGI("Incl %s:%s/%s: 0x%08x\n",
+ String8(package).string(), String8(type).string(),
+ String8(name).string(), rid);
+ }
}
uint32_t packageId = Res_GETPACKAGE(rid) + 1;
@@ -4714,9 +4871,11 @@
uint32_t rid = accessor->getCustomResourceWithCreation(package, type, name,
createIfNotFound);
if (rid != 0) {
- TABLE_NOISY(printf("Pckg %s:%s/%s: 0x%08x\n",
- String8(package).string(), String8(type).string(),
- String8(name).string(), rid));
+ if (kDebugTableNoisy) {
+ ALOGI("Pckg %s:%s/%s: 0x%08x\n",
+ String8(package).string(), String8(type).string(),
+ String8(name).string(), rid);
+ }
uint32_t packageId = Res_GETPACKAGE(rid) + 1;
if (packageId == 0x00) {
outValue->data = rid;
@@ -5519,8 +5678,6 @@
}
// Check if there is the desired entry in this type.
- const uint8_t* const end = reinterpret_cast<const uint8_t*>(thisType)
- + dtohl(thisType->header.size);
const uint32_t* const eindex = reinterpret_cast<const uint32_t*>(
reinterpret_cast<const uint8_t*>(thisType) + dtohs(thisType->header.headerSize));
@@ -5709,9 +5866,11 @@
const uint8_t* endPos = ((const uint8_t*)pkg) + dtohs(pkg->header.size);
while (((const uint8_t*)chunk) <= (endPos-sizeof(ResChunk_header)) &&
((const uint8_t*)chunk) <= (endPos-dtohl(chunk->size))) {
- TABLE_NOISY(ALOGV("PackageChunk: type=0x%x, headerSize=0x%x, size=0x%x, pos=%p\n",
- dtohs(chunk->type), dtohs(chunk->headerSize), dtohl(chunk->size),
- (void*)(((const uint8_t*)chunk) - ((const uint8_t*)header->header))));
+ if (kDebugTableNoisy) {
+ ALOGV("PackageChunk: type=0x%x, headerSize=0x%x, size=0x%x, pos=%p\n",
+ dtohs(chunk->type), dtohs(chunk->headerSize), dtohl(chunk->size),
+ (void*)(((const uint8_t*)chunk) - ((const uint8_t*)header->header)));
+ }
const size_t csize = dtohl(chunk->size);
const uint16_t ctype = dtohs(chunk->type);
if (ctype == RES_TABLE_TYPE_SPEC_TYPE) {
@@ -5725,11 +5884,13 @@
const size_t typeSpecSize = dtohl(typeSpec->header.size);
const size_t newEntryCount = dtohl(typeSpec->entryCount);
- LOAD_TABLE_NOISY(printf("TypeSpec off %p: type=0x%x, headerSize=0x%x, size=%p\n",
- (void*)(base-(const uint8_t*)chunk),
- dtohs(typeSpec->header.type),
- dtohs(typeSpec->header.headerSize),
- (void*)typeSpecSize));
+ if (kDebugLoadTableNoisy) {
+ ALOGI("TypeSpec off %p: type=0x%x, headerSize=0x%x, size=%p\n",
+ (void*)(base-(const uint8_t*)chunk),
+ dtohs(typeSpec->header.type),
+ dtohs(typeSpec->header.headerSize),
+ (void*)typeSpecSize);
+ }
// look for block overrun or int overflow when multiplying by 4
if ((dtohl(typeSpec->entryCount) > (INT32_MAX/sizeof(uint32_t))
|| dtohs(typeSpec->header.headerSize)+(sizeof(uint32_t)*newEntryCount)
@@ -5787,13 +5948,14 @@
const uint32_t typeSize = dtohl(type->header.size);
const size_t newEntryCount = dtohl(type->entryCount);
- LOAD_TABLE_NOISY(printf("Type off %p: type=0x%x, headerSize=0x%x, size=%p\n",
- (void*)(base-(const uint8_t*)chunk),
- dtohs(type->header.type),
- dtohs(type->header.headerSize),
- (void*)typeSize));
- if (dtohs(type->header.headerSize)+(sizeof(uint32_t)*newEntryCount)
- > typeSize) {
+ if (kDebugLoadTableNoisy) {
+ printf("Type off %p: type=0x%x, headerSize=0x%x, size=%u\n",
+ (void*)(base-(const uint8_t*)chunk),
+ dtohs(type->header.type),
+ dtohs(type->header.headerSize),
+ typeSize);
+ }
+ if (dtohs(type->header.headerSize)+(sizeof(uint32_t)*newEntryCount) > typeSize) {
ALOGW("ResTable_type entry index to %p extends beyond chunk end 0x%x.",
(void*)(dtohs(type->header.headerSize) + (sizeof(uint32_t)*newEntryCount)),
typeSize);
@@ -5839,11 +6001,12 @@
t->configs.add(type);
- TABLE_GETENTRY(
+ if (kDebugTableGetEntry) {
ResTable_config thisConfig;
thisConfig.copyFromDtoH(type->config);
- ALOGI("Adding config to type %d: %s\n",
- type->id, thisConfig.toString().string()));
+ ALOGI("Adding config to type %d: %s\n", type->id,
+ thisConfig.toString().string());
+ }
} else {
ALOGV("Skipping empty ResTable_type for type %d", type->id);
}
@@ -5904,8 +6067,10 @@
uint32_t packageId = dtohl(entry->packageId);
char16_t tmpName[sizeof(entry->packageName) / sizeof(char16_t)];
strcpy16_dtoh(tmpName, entry->packageName, sizeof(entry->packageName) / sizeof(char16_t));
- LIB_NOISY(ALOGV("Found lib entry %s with id %d\n", String8(tmpName).string(),
- dtohl(entry->packageId)));
+ if (kDebugLibNoisy) {
+ ALOGV("Found lib entry %s with id %d\n", String8(tmpName).string(),
+ dtohl(entry->packageId));
+ }
if (packageId >= 256) {
ALOGE("Bad package id 0x%08x", packageId);
return UNKNOWN_ERROR;
@@ -6088,7 +6253,7 @@
if (Res_GETTYPE(overlayResID) + 1 != static_cast<size_t>(typeMap.overlayTypeId)) {
ALOGE("idmap: can't mix type ids in entry map. Resource 0x%08x maps to 0x%08x"
- " but entries should map to resources of type %02x",
+ " but entries should map to resources of type %02zx",
resID, overlayResID, typeMap.overlayTypeId);
return BAD_TYPE;
}
@@ -6424,9 +6589,6 @@
continue;
}
for (size_t entryIndex=0; entryIndex<entryCount; entryIndex++) {
-
- const uint8_t* const end = ((const uint8_t*)type)
- + dtohl(type->header.size);
const uint32_t* const eindex = (const uint32_t*)
(((const uint8_t*)type) + dtohs(type->header.headerSize));
diff --git a/libs/androidfw/StreamingZipInflater.cpp b/libs/androidfw/StreamingZipInflater.cpp
index 1dfec23..b39b5f0 100644
--- a/libs/androidfw/StreamingZipInflater.cpp
+++ b/libs/androidfw/StreamingZipInflater.cpp
@@ -41,6 +41,8 @@
_rc; })
#endif
+static const bool kIsDebug = false;
+
static inline size_t min_of(size_t a, size_t b) { return (a < b) ? a : b; }
using namespace android;
@@ -209,7 +211,9 @@
size_t toRead = min_of(mInBufSize, mInTotalSize - mInNextChunkOffset);
if (toRead > 0) {
ssize_t didRead = TEMP_FAILURE_RETRY(::read(mFd, mInBuf, toRead));
- //ALOGV("Reading input chunk, size %08x didread %08x", toRead, didRead);
+ if (kIsDebug) {
+ ALOGV("Reading input chunk, size %08zx didread %08zx", toRead, didRead);
+ }
if (didRead < 0) {
ALOGE("Error reading asset data: %s", strerror(errno));
return didRead;
diff --git a/libs/androidfw/ZipFileRO.cpp b/libs/androidfw/ZipFileRO.cpp
index 1ab18ad..ef0d072 100644
--- a/libs/androidfw/ZipFileRO.cpp
+++ b/libs/androidfw/ZipFileRO.cpp
@@ -34,14 +34,6 @@
#include <assert.h>
#include <unistd.h>
-/*
- * We must open binary files using open(path, ... | O_BINARY) under Windows.
- * Otherwise strange read errors will happen.
- */
-#ifndef O_BINARY
-# define O_BINARY 0
-#endif
-
using namespace android;
class _ZipEntryRO {
@@ -50,7 +42,10 @@
ZipEntryName name;
void *cookie;
- _ZipEntryRO() : cookie(NULL) {
+ _ZipEntryRO() : cookie(NULL) {}
+
+ ~_ZipEntryRO() {
+ EndIteration(cookie);
}
private:
@@ -83,15 +78,15 @@
ZipEntryRO ZipFileRO::findEntryByName(const char* entryName) const
{
_ZipEntryRO* data = new _ZipEntryRO;
- const int32_t error = FindEntry(mHandle, entryName, &(data->entry));
+
+ data->name = ZipEntryName(entryName);
+
+ const int32_t error = FindEntry(mHandle, data->name, &(data->entry));
if (error) {
delete data;
return NULL;
}
- data->name.name = entryName;
- data->name.name_length = strlen(entryName);
-
return (ZipEntryRO) data;
}
diff --git a/libs/androidfw/tests/Android.mk b/libs/androidfw/tests/Android.mk
index 2d7906f..dd45200 100644
--- a/libs/androidfw/tests/Android.mk
+++ b/libs/androidfw/tests/Android.mk
@@ -37,12 +37,17 @@
include $(CLEAR_VARS)
LOCAL_MODULE := libandroidfw_tests
+
+LOCAL_CFLAGS += -Wall -Werror -Wunused -Wunreachable-code
+# gtest is broken.
+LOCAL_CFLAGS += -Wno-unnamed-type-template-args
+
LOCAL_SRC_FILES := $(testFiles)
LOCAL_STATIC_LIBRARIES := \
libandroidfw \
libutils \
libcutils \
- liblog
+ liblog
include $(BUILD_HOST_NATIVE_TEST)
@@ -54,6 +59,11 @@
include $(CLEAR_VARS)
LOCAL_MODULE := libandroidfw_tests
+
+LOCAL_CFLAGS += -Wall -Werror -Wunused -Wunreachable-code
+# gtest is broken.
+LOCAL_CFLAGS += -Wno-unnamed-type-template-args
+
LOCAL_SRC_FILES := $(testFiles) \
BackupData_test.cpp \
ObbFile_test.cpp
@@ -62,7 +72,6 @@
libcutils \
libutils \
libui \
- libstlport
include $(BUILD_NATIVE_TEST)
endif # Not SDK_ONLY
diff --git a/libs/hwui/AmbientShadow.cpp b/libs/hwui/AmbientShadow.cpp
index 21c869b..0fb9bc9 100644
--- a/libs/hwui/AmbientShadow.cpp
+++ b/libs/hwui/AmbientShadow.cpp
@@ -60,6 +60,7 @@
#include "AmbientShadow.h"
#include "ShadowTessellator.h"
#include "Vertex.h"
+#include "VertexBuffer.h"
#include "utils/MathUtils.h"
namespace android {
diff --git a/libs/hwui/AmbientShadow.h b/libs/hwui/AmbientShadow.h
index 9660dc0..8eb1048f 100644
--- a/libs/hwui/AmbientShadow.h
+++ b/libs/hwui/AmbientShadow.h
@@ -19,13 +19,13 @@
#define ANDROID_HWUI_AMBIENT_SHADOW_H
#include "Debug.h"
-#include "OpenGLRenderer.h"
#include "Vector.h"
-#include "VertexBuffer.h"
namespace android {
namespace uirenderer {
+class VertexBuffer;
+
/**
* AmbientShadow is used to calculate the ambient shadow value around a polygon.
*/
diff --git a/libs/hwui/Android.mk b/libs/hwui/Android.mk
index 49560ff..51f257f 100644
--- a/libs/hwui/Android.mk
+++ b/libs/hwui/Android.mk
@@ -1,5 +1,14 @@
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
+LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
+
+# Too many unused parameters in external/skia/include and this directory.
+# getConfig in external/skia/include/core/SkBitmap.h is deprecated.
+# Allow Gnu extension: in-class initializer of static 'const float' member.
+LOCAL_CLANG_CFLAGS += \
+ -Wno-unused-parameter \
+ -Wno-deprecated-declarations \
+ -Wno-gnu-static-float-init
# Only build libhwui when USE_OPENGL_RENDERER is
# defined in the current device/board configuration
@@ -16,10 +25,9 @@
Animator.cpp \
AnimatorManager.cpp \
AssetAtlas.cpp \
- DamageAccumulator.cpp \
- FontRenderer.cpp \
- GammaFontRenderer.cpp \
Caches.cpp \
+ CanvasState.cpp \
+ DamageAccumulator.cpp \
DisplayList.cpp \
DeferredDisplayList.cpp \
DeferredLayerUpdater.cpp \
@@ -29,6 +37,8 @@
DrawProfiler.cpp \
Extensions.cpp \
FboCache.cpp \
+ FontRenderer.cpp \
+ GammaFontRenderer.cpp \
GradientCache.cpp \
Image.cpp \
Interpolator.cpp \
@@ -53,7 +63,6 @@
SkiaShader.cpp \
Snapshot.cpp \
SpotShadow.cpp \
- StatefulBaseRenderer.cpp \
Stencil.cpp \
TessellationCache.cpp \
Texture.cpp \
@@ -82,15 +91,14 @@
LOCAL_MODULE := libhwui
LOCAL_MODULE_TAGS := optional
- include external/stlport/libstlport.mk
-
ifneq (false,$(ANDROID_ENABLE_RENDERSCRIPT))
LOCAL_CFLAGS += -DANDROID_ENABLE_RENDERSCRIPT
LOCAL_SHARED_LIBRARIES += libRS libRScpp
LOCAL_C_INCLUDES += \
$(intermediates) \
frameworks/rs/cpp \
- frameworks/rs
+ frameworks/rs \
+
endif
ifndef HWUI_COMPILE_SYMBOLS
@@ -104,6 +112,7 @@
# Defaults for ATRACE_TAG and LOG_TAG for libhwui
LOCAL_CFLAGS += -DATRACE_TAG=ATRACE_TAG_VIEW -DLOG_TAG=\"OpenGLRenderer\"
+ include external/stlport/libstlport.mk
include $(BUILD_SHARED_LIBRARY)
include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/libs/hwui/Animator.cpp b/libs/hwui/Animator.cpp
index 8bf2107..a1bbc06 100644
--- a/libs/hwui/Animator.cpp
+++ b/libs/hwui/Animator.cpp
@@ -20,6 +20,7 @@
#include <set>
#include "AnimationContext.h"
+#include "Interpolator.h"
#include "RenderNode.h"
#include "RenderProperties.h"
diff --git a/libs/hwui/Animator.h b/libs/hwui/Animator.h
index 35a4a09..99f8956 100644
--- a/libs/hwui/Animator.h
+++ b/libs/hwui/Animator.h
@@ -19,10 +19,8 @@
#include <cutils/compiler.h>
#include <utils/RefBase.h>
#include <utils/StrongPointer.h>
+#include <utils/Timers.h>
-#include "CanvasProperty.h"
-#include "Interpolator.h"
-#include "TreeInfo.h"
#include "utils/Macros.h"
namespace android {
@@ -30,6 +28,9 @@
class AnimationContext;
class BaseRenderNodeAnimator;
+class CanvasPropertyPrimitive;
+class CanvasPropertyPaint;
+class Interpolator;
class RenderNode;
class RenderProperties;
diff --git a/libs/hwui/AnimatorManager.cpp b/libs/hwui/AnimatorManager.cpp
index c28fb88..9a4ba21 100644
--- a/libs/hwui/AnimatorManager.cpp
+++ b/libs/hwui/AnimatorManager.cpp
@@ -17,7 +17,9 @@
#include <algorithm>
+#include "Animator.h"
#include "AnimationContext.h"
+#include "DamageAccumulator.h"
#include "RenderNode.h"
namespace android {
diff --git a/libs/hwui/AnimatorManager.h b/libs/hwui/AnimatorManager.h
index d03d427..fb75eb8 100644
--- a/libs/hwui/AnimatorManager.h
+++ b/libs/hwui/AnimatorManager.h
@@ -21,7 +21,6 @@
#include <cutils/compiler.h>
#include <utils/StrongPointer.h>
-#include "TreeInfo.h"
#include "utils/Macros.h"
namespace android {
@@ -30,6 +29,7 @@
class AnimationHandle;
class BaseRenderNodeAnimator;
class RenderNode;
+class TreeInfo;
// Responsible for managing the animators for a single RenderNode
class AnimatorManager {
diff --git a/libs/hwui/AssetAtlas.cpp b/libs/hwui/AssetAtlas.cpp
index fc86e4f..faec5d2 100644
--- a/libs/hwui/AssetAtlas.cpp
+++ b/libs/hwui/AssetAtlas.cpp
@@ -18,6 +18,7 @@
#include "AssetAtlas.h"
#include "Caches.h"
+#include "Image.h"
#include <GLES2/gl2ext.h>
diff --git a/libs/hwui/AssetAtlas.h b/libs/hwui/AssetAtlas.h
index 2ec556e..6f72793 100644
--- a/libs/hwui/AssetAtlas.h
+++ b/libs/hwui/AssetAtlas.h
@@ -27,7 +27,6 @@
#include <SkBitmap.h>
-#include "Image.h"
#include "Texture.h"
#include "UvMapper.h"
@@ -35,6 +34,7 @@
namespace uirenderer {
class Caches;
+class Image;
/**
* An asset atlas holds a collection of framework bitmaps in a single OpenGL
diff --git a/libs/hwui/Caches.cpp b/libs/hwui/Caches.cpp
index 952f739..23635fd1 100644
--- a/libs/hwui/Caches.cpp
+++ b/libs/hwui/Caches.cpp
@@ -21,6 +21,7 @@
#include "Caches.h"
#include "DisplayListRenderer.h"
+#include "GammaFontRenderer.h"
#include "Properties.h"
#include "LayerRenderer.h"
#include "ShadowTessellator.h"
diff --git a/libs/hwui/Caches.h b/libs/hwui/Caches.h
index e338686..4b8b626 100644
--- a/libs/hwui/Caches.h
+++ b/libs/hwui/Caches.h
@@ -31,13 +31,13 @@
#include <cutils/compiler.h>
+#include <SkPath.h>
+
#include "thread/TaskProcessor.h"
#include "thread/TaskManager.h"
#include "AssetAtlas.h"
#include "Extensions.h"
-#include "FontRenderer.h"
-#include "GammaFontRenderer.h"
#include "TextureCache.h"
#include "LayerCache.h"
#include "RenderBufferCache.h"
@@ -55,6 +55,8 @@
namespace android {
namespace uirenderer {
+class GammaFontRenderer;
+
///////////////////////////////////////////////////////////////////////////////
// Globals
///////////////////////////////////////////////////////////////////////////////
diff --git a/libs/hwui/StatefulBaseRenderer.cpp b/libs/hwui/CanvasState.cpp
similarity index 71%
rename from libs/hwui/StatefulBaseRenderer.cpp
rename to libs/hwui/CanvasState.cpp
index 88d6f68..20cc17e 100644
--- a/libs/hwui/StatefulBaseRenderer.cpp
+++ b/libs/hwui/CanvasState.cpp
@@ -14,41 +14,45 @@
* limitations under the License.
*/
-#define LOG_TAG "OpenGLRenderer"
-
#include <SkCanvas.h>
-#include "StatefulBaseRenderer.h"
-
+#include "CanvasState.h"
#include "utils/MathUtils.h"
namespace android {
namespace uirenderer {
-StatefulBaseRenderer::StatefulBaseRenderer()
+
+CanvasState::CanvasState(CanvasStateClient& renderer)
: mDirtyClip(false)
, mWidth(-1)
, mHeight(-1)
, mSaveCount(1)
, mFirstSnapshot(new Snapshot)
+ , mCanvas(renderer)
, mSnapshot(mFirstSnapshot) {
+
}
-void StatefulBaseRenderer::initializeSaveStack(float clipLeft, float clipTop,
+CanvasState::~CanvasState() {
+
+}
+
+void CanvasState::initializeSaveStack(float clipLeft, float clipTop,
float clipRight, float clipBottom, const Vector3& lightCenter) {
mSnapshot = new Snapshot(mFirstSnapshot,
SkCanvas::kMatrix_SaveFlag | SkCanvas::kClip_SaveFlag);
mSnapshot->setClip(clipLeft, clipTop, clipRight, clipBottom);
- mSnapshot->fbo = getTargetFbo();
+ mSnapshot->fbo = mCanvas.onGetTargetFbo();
mSnapshot->setRelativeLightCenter(lightCenter);
mSaveCount = 1;
}
-void StatefulBaseRenderer::setViewport(int width, int height) {
+void CanvasState::setViewport(int width, int height) {
mWidth = width;
mHeight = height;
mFirstSnapshot->initializeViewport(width, height);
- onViewportInitialized();
+ mCanvas.onViewportInitialized();
// create a temporary 1st snapshot, so old snapshots are released,
// and viewport can be queried safely.
@@ -63,24 +67,24 @@
///////////////////////////////////////////////////////////////////////////////
/**
- * Non-virtual implementation of save, guaranteed to save without side-effects
+ * Guaranteed to save without side-effects
*
- * The approach here and in restoreSnapshot(), allows subclasses to directly manipulate the save
+ * This approach, here and in restoreSnapshot(), allows subclasses to directly manipulate the save
* stack, and ensures restoreToCount() doesn't call back into subclass overrides.
*/
-int StatefulBaseRenderer::saveSnapshot(int flags) {
+int CanvasState::saveSnapshot(int flags) {
mSnapshot = new Snapshot(mSnapshot, flags);
return mSaveCount++;
}
-int StatefulBaseRenderer::save(int flags) {
+int CanvasState::save(int flags) {
return saveSnapshot(flags);
}
/**
- * Non-virtual implementation of restore, guaranteed to restore without side-effects.
+ * Guaranteed to restore without side-effects.
*/
-void StatefulBaseRenderer::restoreSnapshot() {
+void CanvasState::restoreSnapshot() {
sp<Snapshot> toRemove = mSnapshot;
sp<Snapshot> toRestore = mSnapshot->previous;
@@ -88,16 +92,16 @@
mSnapshot = toRestore;
// subclass handles restore implementation
- onSnapshotRestored(*toRemove, *toRestore);
+ mCanvas.onSnapshotRestored(*toRemove, *toRestore);
}
-void StatefulBaseRenderer::restore() {
+void CanvasState::restore() {
if (mSaveCount > 1) {
restoreSnapshot();
}
}
-void StatefulBaseRenderer::restoreToCount(int saveCount) {
+void CanvasState::restoreToCount(int saveCount) {
if (saveCount < 1) saveCount = 1;
while (mSaveCount > saveCount) {
@@ -109,40 +113,40 @@
// Matrix
///////////////////////////////////////////////////////////////////////////////
-void StatefulBaseRenderer::getMatrix(SkMatrix* matrix) const {
+void CanvasState::getMatrix(SkMatrix* matrix) const {
mSnapshot->transform->copyTo(*matrix);
}
-void StatefulBaseRenderer::translate(float dx, float dy, float dz) {
+void CanvasState::translate(float dx, float dy, float dz) {
mSnapshot->transform->translate(dx, dy, dz);
}
-void StatefulBaseRenderer::rotate(float degrees) {
+void CanvasState::rotate(float degrees) {
mSnapshot->transform->rotate(degrees, 0.0f, 0.0f, 1.0f);
}
-void StatefulBaseRenderer::scale(float sx, float sy) {
+void CanvasState::scale(float sx, float sy) {
mSnapshot->transform->scale(sx, sy, 1.0f);
}
-void StatefulBaseRenderer::skew(float sx, float sy) {
+void CanvasState::skew(float sx, float sy) {
mSnapshot->transform->skew(sx, sy);
}
-void StatefulBaseRenderer::setMatrix(const SkMatrix& matrix) {
+void CanvasState::setMatrix(const SkMatrix& matrix) {
mSnapshot->transform->load(matrix);
}
-void StatefulBaseRenderer::setMatrix(const Matrix4& matrix) {
+void CanvasState::setMatrix(const Matrix4& matrix) {
mSnapshot->transform->load(matrix);
}
-void StatefulBaseRenderer::concatMatrix(const SkMatrix& matrix) {
+void CanvasState::concatMatrix(const SkMatrix& matrix) {
mat4 transform(matrix);
mSnapshot->transform->multiply(transform);
}
-void StatefulBaseRenderer::concatMatrix(const Matrix4& matrix) {
+void CanvasState::concatMatrix(const Matrix4& matrix) {
mSnapshot->transform->multiply(matrix);
}
@@ -150,7 +154,7 @@
// Clip
///////////////////////////////////////////////////////////////////////////////
-bool StatefulBaseRenderer::clipRect(float left, float top, float right, float bottom, SkRegion::Op op) {
+bool CanvasState::clipRect(float left, float top, float right, float bottom, SkRegion::Op op) {
if (CC_LIKELY(currentTransform()->rectToRect())) {
mDirtyClip |= mSnapshot->clip(left, top, right, bottom, op);
return !mSnapshot->clipRect->isEmpty();
@@ -159,10 +163,10 @@
SkPath path;
path.addRect(left, top, right, bottom);
- return StatefulBaseRenderer::clipPath(&path, op);
+ return CanvasState::clipPath(&path, op);
}
-bool StatefulBaseRenderer::clipPath(const SkPath* path, SkRegion::Op op) {
+bool CanvasState::clipPath(const SkPath* path, SkRegion::Op op) {
SkMatrix transform;
currentTransform()->copyTo(transform);
@@ -189,12 +193,12 @@
return !mSnapshot->clipRect->isEmpty();
}
-bool StatefulBaseRenderer::clipRegion(const SkRegion* region, SkRegion::Op op) {
+bool CanvasState::clipRegion(const SkRegion* region, SkRegion::Op op) {
mDirtyClip |= mSnapshot->clipRegionTransformed(*region, op);
return !mSnapshot->clipRect->isEmpty();
}
-void StatefulBaseRenderer::setClippingOutline(LinearAllocator& allocator, const Outline* outline) {
+void CanvasState::setClippingOutline(LinearAllocator& allocator, const Outline* outline) {
Rect bounds;
float radius;
if (!outline->getAsRoundRect(&bounds, &radius)) return; // only RR supported
@@ -209,7 +213,7 @@
}
}
-void StatefulBaseRenderer::setClippingRoundRect(LinearAllocator& allocator,
+void CanvasState::setClippingRoundRect(LinearAllocator& allocator,
const Rect& rect, float radius, bool highPriority) {
mSnapshot->setClippingRoundRect(allocator, rect, radius, highPriority);
}
@@ -229,7 +233,7 @@
* @param snapOut if set, the geometry will be treated as having an AA ramp.
* See Rect::snapGeometryToPixelBoundaries()
*/
-bool StatefulBaseRenderer::calculateQuickRejectForScissor(float left, float top,
+bool CanvasState::calculateQuickRejectForScissor(float left, float top,
float right, float bottom,
bool* clipRequired, bool* roundRectClipRequired,
bool snapOut) const {
@@ -259,18 +263,7 @@
return false;
}
-/**
- * Returns false if drawing won't be clipped out.
- *
- * Makes the decision conservatively, by rounding out the mapped rect before comparing with the
- * clipRect. To be used when perfect, pixel accuracy is not possible (esp. with tessellation) but
- * rejection is still desired.
- *
- * This function, unlike quickRejectSetupScissor, should be used where precise geometry information
- * isn't known (esp. when geometry adjusts based on scale). Generally, this will be first pass
- * rejection where precise rejection isn't important, or precise information isn't available.
- */
-bool StatefulBaseRenderer::quickRejectConservative(float left, float top,
+bool CanvasState::quickRejectConservative(float left, float top,
float right, float bottom) const {
if (mSnapshot->isIgnored() || bottom <= top || right <= left) {
return true;
@@ -288,5 +281,5 @@
return false;
}
-}; // namespace uirenderer
-}; // namespace android
+} // namespace uirenderer
+} // namespace android
diff --git a/libs/hwui/CanvasState.h b/libs/hwui/CanvasState.h
new file mode 100644
index 0000000..6883d0a
--- /dev/null
+++ b/libs/hwui/CanvasState.h
@@ -0,0 +1,196 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_HWUI_CANVAS_STATE_H
+#define ANDROID_HWUI_CANVAS_STATE_H
+
+#include <SkMatrix.h>
+#include <SkPath.h>
+#include <SkRegion.h>
+
+#include "Snapshot.h"
+
+namespace android {
+namespace uirenderer {
+
+/**
+ * Abstract base class for any class containing CanvasState.
+ * Defines three mandatory callbacks.
+ */
+class CanvasStateClient {
+public:
+ CanvasStateClient() { }
+ virtual ~CanvasStateClient() { }
+
+ /**
+ * Callback allowing embedder to take actions in the middle of a
+ * setViewport() call.
+ */
+ virtual void onViewportInitialized() = 0;
+
+ /**
+ * Callback allowing embedder to take actions in the middle of a
+ * restore() call. May be called several times sequentially.
+ */
+ virtual void onSnapshotRestored(const Snapshot& removed, const Snapshot& restored) = 0;
+
+ /**
+ * Allows subclasses to control what value is stored in snapshot's
+ * fbo field in * initializeSaveStack.
+ */
+ virtual GLuint onGetTargetFbo() const = 0;
+
+}; // class CanvasStateClient
+
+/**
+ * Implements Canvas state methods on behalf of Renderers.
+ *
+ * Manages the Snapshot stack, implementing matrix, save/restore, and clipping methods in the
+ * Renderer interface. Drawing and recording classes that include a CanvasState will have
+ * different use cases:
+ *
+ * Drawing subclasses (i.e. OpenGLRenderer) can query attributes (such as transform) or hook into
+ * changes (e.g. save/restore) with minimal surface area for manipulating the stack itself.
+ *
+ * Recording subclasses (i.e. DisplayListRenderer) can both record and pass through state operations
+ * to CanvasState, so that not only will querying operations work (getClip/Matrix), but so
+ * that quickRejection can also be used.
+ */
+
+class ANDROID_API CanvasState {
+public:
+ CanvasState(CanvasStateClient& renderer);
+ ~CanvasState();
+
+ /**
+ * Initializes the first snapshot, computing the projection matrix,
+ * and stores the dimensions of the render target.
+ */
+ void initializeSaveStack(float clipLeft, float clipTop, float clipRight, float clipBottom,
+ const Vector3& lightCenter);
+
+ void setViewport(int width, int height);
+
+ bool hasRectToRectTransform() const {
+ return CC_LIKELY(currentTransform()->rectToRect());
+ }
+
+ // Save (layer)
+ int getSaveCount() const { return mSaveCount; }
+ int save(int flags);
+ void restore();
+ void restoreToCount(int saveCount);
+
+ // Save/Restore without side-effects
+ int saveSnapshot(int flags);
+ void restoreSnapshot();
+
+ // Matrix
+ void getMatrix(SkMatrix* outMatrix) const;
+ void translate(float dx, float dy, float dz = 0.0f);
+ void rotate(float degrees);
+ void scale(float sx, float sy);
+ void skew(float sx, float sy);
+
+ void setMatrix(const SkMatrix& matrix);
+ void setMatrix(const Matrix4& matrix); // internal only convenience method
+ void concatMatrix(const SkMatrix& matrix);
+ void concatMatrix(const Matrix4& matrix); // internal only convenience method
+
+ // Clip
+ const Rect& getLocalClipBounds() const { return mSnapshot->getLocalClip(); }
+ const Rect& getRenderTargetClipBounds() const { return mSnapshot->getRenderTargetClip(); }
+
+ bool quickRejectConservative(float left, float top, float right, float bottom) const;
+
+ bool clipRect(float left, float top, float right, float bottom, SkRegion::Op op);
+ bool clipPath(const SkPath* path, SkRegion::Op op);
+ bool clipRegion(const SkRegion* region, SkRegion::Op op);
+
+ bool isCurrentClipSimple() const {
+ return currentSnapshot()->clipRegion->isEmpty();
+ }
+
+ /**
+ * Sets a "clipping outline", which is independent from the regular clip.
+ * Currently only supports rectangles or rounded rectangles; passing in a
+ * more complicated outline fails silently. Replaces any previous clipping
+ * outline.
+ */
+ void setClippingOutline(LinearAllocator& allocator, const Outline* outline);
+ void setClippingRoundRect(LinearAllocator& allocator,
+ const Rect& rect, float radius, bool highPriority = true);
+
+ /**
+ * Returns true if drawing in the rectangle (left, top, right, bottom)
+ * will be clipped out. Is conservative: might return false when subpixel-
+ * perfect tests would return true.
+ */
+ bool calculateQuickRejectForScissor(float left, float top, float right, float bottom,
+ bool* clipRequired, bool* roundRectClipRequired, bool snapOut) const;
+
+ void setDirtyClip(bool opaque) { mDirtyClip = opaque; }
+ bool getDirtyClip() const { return mDirtyClip; }
+
+ void scaleAlpha(float alpha) { mSnapshot->alpha *= alpha; }
+ void setEmpty(bool value) { mSnapshot->empty = value; }
+ void setInvisible(bool value) { mSnapshot->invisible = value; }
+
+ inline const mat4* currentTransform() const { return currentSnapshot()->transform; }
+ inline const Rect* currentClipRect() const { return currentSnapshot()->clipRect; }
+ inline Region* currentRegion() const { return currentSnapshot()->region; }
+ inline int currentFlags() const { return currentSnapshot()->flags; }
+ const Vector3& currentLightCenter() const { return currentSnapshot()->getRelativeLightCenter(); }
+ inline bool currentlyIgnored() const { return currentSnapshot()->isIgnored(); }
+ int getViewportWidth() const { return currentSnapshot()->getViewportWidth(); }
+ int getViewportHeight() const { return currentSnapshot()->getViewportHeight(); }
+ int getWidth() { return mWidth; }
+ int getHeight() { return mHeight; }
+
+ inline const Snapshot* currentSnapshot() const {
+ return mSnapshot != NULL ? mSnapshot.get() : mFirstSnapshot.get();
+ }
+ inline Snapshot* writableSnapshot() { return mSnapshot.get(); }
+ inline const Snapshot* firstSnapshot() const { return mFirstSnapshot.get(); }
+
+private:
+ /// No default constructor - must supply a CanvasStateClient (mCanvas).
+ CanvasState();
+
+ /// indicates that the clip has been changed since the last time it was consumed
+ bool mDirtyClip;
+
+ /// Dimensions of the drawing surface
+ int mWidth, mHeight;
+
+ /// Number of saved states
+ int mSaveCount;
+
+ /// Base state
+ sp<Snapshot> mFirstSnapshot;
+
+ /// Host providing callbacks
+ CanvasStateClient& mCanvas;
+
+ /// Current state
+ sp<Snapshot> mSnapshot;
+
+}; // class CanvasState
+
+}; // namespace uirenderer
+}; // namespace android
+
+#endif // ANDROID_HWUI_CANVAS_STATE_H
diff --git a/libs/hwui/DeferredDisplayList.cpp b/libs/hwui/DeferredDisplayList.cpp
index fab4a1a..a5e48e9 100644
--- a/libs/hwui/DeferredDisplayList.cpp
+++ b/libs/hwui/DeferredDisplayList.cpp
@@ -52,7 +52,7 @@
class Batch {
public:
- virtual status_t replay(OpenGLRenderer& renderer, Rect& dirty, int index) = 0;
+ virtual void replay(OpenGLRenderer& renderer, Rect& dirty, int index) = 0;
virtual ~Batch() {}
virtual bool purelyDrawBatch() { return false; }
virtual bool coversBounds(const Rect& bounds) { return false; }
@@ -91,11 +91,10 @@
return false;
}
- virtual status_t replay(OpenGLRenderer& renderer, Rect& dirty, int index) {
+ virtual void replay(OpenGLRenderer& renderer, Rect& dirty, int index) {
DEFER_LOGD("%d replaying DrawBatch %p, with %d ops (batch id %x, merge id %p)",
index, this, mOps.size(), getBatchId(), getMergeId());
- status_t status = DrawGlInfo::kStatusDone;
DisplayListLogBuffer& logBuffer = DisplayListLogBuffer::getInstance();
for (unsigned int i = 0; i < mOps.size(); i++) {
DrawOp* op = mOps[i].op;
@@ -106,7 +105,7 @@
renderer.eventMark(op->name());
#endif
logBuffer.writeCommand(0, op->name());
- status |= op->applyDraw(renderer, dirty);
+ op->applyDraw(renderer, dirty);
#if DEBUG_MERGE_BEHAVIOR
const Rect& bounds = state->mBounds;
@@ -118,7 +117,6 @@
batchColor);
#endif
}
- return status;
}
virtual bool purelyDrawBatch() { return true; }
@@ -235,26 +233,6 @@
return false;
}
- /* Draw Modifiers compatibility check
- *
- * Shadows are ignored, as only text uses them, and in that case they are drawn
- * per-DrawTextOp, before the unified text draw. Because of this, it's always safe to merge
- * text UNLESS a later draw's shadow should overlays a previous draw's text. This is covered
- * above with the intersection check.
- *
- * OverrideLayerAlpha is also ignored, as it's only used for drawing layers, which are never
- * merged.
- *
- * These ignore cases prevent us from simply memcmp'ing the drawModifiers
- */
- const DrawModifiers& lhsMod = lhs->mDrawModifiers;
- const DrawModifiers& rhsMod = rhs->mDrawModifiers;
-
- // Draw filter testing expects bit fields to be clear if filter not set.
- if (lhsMod.mHasDrawFilter != rhsMod.mHasDrawFilter) return false;
- if (lhsMod.mPaintFilterClearBits != rhsMod.mPaintFilterClearBits) return false;
- if (lhsMod.mPaintFilterSetBits != rhsMod.mPaintFilterSetBits) return false;
-
return true;
}
@@ -269,12 +247,13 @@
if (newClipSideFlags & kClipSide_Bottom) mClipRect.bottom = state->mClip.bottom;
}
- virtual status_t replay(OpenGLRenderer& renderer, Rect& dirty, int index) {
+ virtual void replay(OpenGLRenderer& renderer, Rect& dirty, int index) {
DEFER_LOGD("%d replaying MergingDrawBatch %p, with %d ops,"
" clip flags %x (batch id %x, merge id %p)",
index, this, mOps.size(), mClipSideFlags, getBatchId(), getMergeId());
if (mOps.size() == 1) {
- return DrawBatch::replay(renderer, dirty, -1);
+ DrawBatch::replay(renderer, dirty, -1);
+ return;
}
// clipping in the merged case is done ahead of time since all ops share the clip (if any)
@@ -289,13 +268,12 @@
renderer.eventMark("multiDraw");
renderer.eventMark(op->name());
#endif
- status_t status = op->multiDraw(renderer, dirty, mOps, mBounds);
+ op->multiDraw(renderer, dirty, mOps, mBounds);
#if DEBUG_MERGE_BEHAVIOR
renderer.drawScreenSpaceColorRect(mBounds.left, mBounds.top, mBounds.right, mBounds.bottom,
DEBUG_COLOR_MERGEDBATCH);
#endif
- return status;
}
private:
@@ -313,7 +291,7 @@
// creates a single operation batch
StateOpBatch(const StateOp* op, const DeferredDisplayState* state) : mOp(op), mState(state) {}
- virtual status_t replay(OpenGLRenderer& renderer, Rect& dirty, int index) {
+ virtual void replay(OpenGLRenderer& renderer, Rect& dirty, int index) {
DEFER_LOGD("replaying state op batch %p", this);
renderer.restoreDisplayState(*mState);
@@ -322,7 +300,6 @@
// renderer.restoreToCount directly
int saveCount = -1;
mOp->applyState(renderer, saveCount);
- return DrawGlInfo::kStatusDone;
}
private:
@@ -335,12 +312,11 @@
RestoreToCountBatch(const StateOp* op, const DeferredDisplayState* state, int restoreCount) :
mOp(op), mState(state), mRestoreCount(restoreCount) {}
- virtual status_t replay(OpenGLRenderer& renderer, Rect& dirty, int index) {
+ virtual void replay(OpenGLRenderer& renderer, Rect& dirty, int index) {
DEFER_LOGD("batch %p restoring to count %d", this, mRestoreCount);
renderer.restoreDisplayState(*mState);
renderer.restoreToCount(mRestoreCount);
- return DrawGlInfo::kStatusDone;
}
private:
@@ -359,9 +335,8 @@
#if DEBUG_MERGE_BEHAVIOR
class BarrierDebugBatch : public Batch {
- virtual status_t replay(OpenGLRenderer& renderer, Rect& dirty, int index) {
+ virtual void replay(OpenGLRenderer& renderer, Rect& dirty, int index) {
renderer.drawScreenSpaceColorRect(0, 0, 10000, 10000, DEBUG_COLOR_BARRIER);
- return DrawGlInfo::kStatusDrew;
}
};
#endif
@@ -648,26 +623,22 @@
// Replay / flush
/////////////////////////////////////////////////////////////////////////////////
-static status_t replayBatchList(const Vector<Batch*>& batchList,
+static void replayBatchList(const Vector<Batch*>& batchList,
OpenGLRenderer& renderer, Rect& dirty) {
- status_t status = DrawGlInfo::kStatusDone;
for (unsigned int i = 0; i < batchList.size(); i++) {
if (batchList[i]) {
- status |= batchList[i]->replay(renderer, dirty, i);
+ batchList[i]->replay(renderer, dirty, i);
}
}
DEFER_LOGD("--flushed, drew %d batches", batchList.size());
- return status;
}
-status_t DeferredDisplayList::flush(OpenGLRenderer& renderer, Rect& dirty) {
+void DeferredDisplayList::flush(OpenGLRenderer& renderer, Rect& dirty) {
ATRACE_NAME("flush drawing commands");
Caches::getInstance().fontRenderer->endPrecaching();
- status_t status = DrawGlInfo::kStatusDone;
-
- if (isEmpty()) return status; // nothing to flush
+ if (isEmpty()) return; // nothing to flush
renderer.restoreToCount(1);
DEFER_LOGD("--flushing");
@@ -685,14 +656,13 @@
// NOTE: depth of the save stack at this point, before playback, should be reflected in
// FLUSH_SAVE_STACK_DEPTH, so that save/restores match up correctly
- status |= replayBatchList(mBatches, renderer, dirty);
+ replayBatchList(mBatches, renderer, dirty);
renderer.restoreToCount(1);
renderer.setDrawModifiers(restoreDrawModifiers);
DEFER_LOGD("--flush complete, returning %x", status);
clear();
- return status;
}
void DeferredDisplayList::discardDrawingBatches(const unsigned int maxIndex) {
diff --git a/libs/hwui/DeferredDisplayList.h b/libs/hwui/DeferredDisplayList.h
index 885b411..9e48d3c 100644
--- a/libs/hwui/DeferredDisplayList.h
+++ b/libs/hwui/DeferredDisplayList.h
@@ -106,7 +106,7 @@
* Plays back all of the draw ops recorded into batches to the renderer.
* Adjusts the state of the renderer as necessary, and restores it when complete
*/
- status_t flush(OpenGLRenderer& renderer, Rect& dirty);
+ void flush(OpenGLRenderer& renderer, Rect& dirty);
void addClip(OpenGLRenderer& renderer, ClipOp* op);
void addSaveLayer(OpenGLRenderer& renderer, SaveLayerOp* op, int newSaveCount);
diff --git a/libs/hwui/DeferredLayerUpdater.h b/libs/hwui/DeferredLayerUpdater.h
index 84411ed..ef385b9 100644
--- a/libs/hwui/DeferredLayerUpdater.h
+++ b/libs/hwui/DeferredLayerUpdater.h
@@ -24,7 +24,6 @@
#include "Layer.h"
#include "Rect.h"
-#include "RenderNode.h"
#include "renderthread/RenderThread.h"
namespace android {
diff --git a/libs/hwui/DisplayList.h b/libs/hwui/DisplayList.h
index cb8a8d1..85c2367 100644
--- a/libs/hwui/DisplayList.h
+++ b/libs/hwui/DisplayList.h
@@ -38,8 +38,9 @@
#include <androidfw/ResourceTypes.h>
#include "Debug.h"
-#include "Matrix.h"
+#include "CanvasProperty.h"
#include "DeferredDisplayList.h"
+#include "Matrix.h"
#include "RenderProperties.h"
class SkBitmap;
@@ -104,10 +105,9 @@
public:
ReplayStateStruct(OpenGLRenderer& renderer, Rect& dirty, int replayFlags)
: PlaybackStateStruct(renderer, replayFlags, &mReplayAllocator),
- mDirty(dirty), mDrawGlStatus(DrawGlInfo::kStatusDone) {}
+ mDirty(dirty) {}
Rect& mDirty;
- status_t mDrawGlStatus;
LinearAllocator mReplayAllocator;
};
diff --git a/libs/hwui/DisplayListOp.h b/libs/hwui/DisplayListOp.h
index d78c1cb..7627163 100644
--- a/libs/hwui/DisplayListOp.h
+++ b/libs/hwui/DisplayListOp.h
@@ -32,6 +32,9 @@
#include "AssetAtlas.h"
#include "DeferredDisplayList.h"
#include "DisplayListRenderer.h"
+#include "GammaFontRenderer.h"
+#include "Patch.h"
+#include "RenderNode.h"
#include "UvMapper.h"
#include "utils/LinearAllocator.h"
@@ -132,10 +135,10 @@
return;
}
- replayStruct.mDrawGlStatus |= applyDraw(replayStruct.mRenderer, replayStruct.mDirty);
+ applyDraw(replayStruct.mRenderer, replayStruct.mDirty);
}
- virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty) = 0;
+ virtual void applyDraw(OpenGLRenderer& renderer, Rect& dirty) = 0;
/**
* Draw multiple instances of an operation, must be overidden for operations that merge
@@ -144,14 +147,12 @@
* and pure translation transformations. Other guarantees of similarity should be enforced by
* reducing which operations are tagged as mergeable.
*/
- virtual status_t multiDraw(OpenGLRenderer& renderer, Rect& dirty,
+ virtual void multiDraw(OpenGLRenderer& renderer, Rect& dirty,
const Vector<OpStatePair>& ops, const Rect& bounds) {
- status_t status = DrawGlInfo::kStatusDone;
for (unsigned int i = 0; i < ops.size(); i++) {
renderer.restoreDisplayState(*(ops[i].state), true);
- status |= ops[i].op->applyDraw(renderer, dirty);
+ ops[i].op->applyDraw(renderer, dirty);
}
- return status;
}
/**
@@ -198,10 +199,6 @@
}
protected:
- const SkPaint* getPaint(OpenGLRenderer& renderer) {
- return renderer.filterPaint(mPaint);
- }
-
// Helper method for determining op opaqueness. Assumes op fills its bounds in local
// coordinates, and that paint's alpha is used
inline bool isOpaqueOverBounds(const DeferredDisplayState& state) {
@@ -231,7 +228,7 @@
}
- const SkPaint* mPaint; // should be accessed via getPaint() when applying
+ const SkPaint* mPaint;
bool mQuickRejected;
};
@@ -605,39 +602,6 @@
const SkRegion* mRegion;
};
-class ResetPaintFilterOp : public StateOp {
-public:
- virtual void applyState(OpenGLRenderer& renderer, int saveCount) const {
- renderer.resetPaintFilter();
- }
-
- virtual void output(int level, uint32_t logFlags) const {
- OP_LOGS("ResetPaintFilter");
- }
-
- virtual const char* name() { return "ResetPaintFilter"; }
-};
-
-class SetupPaintFilterOp : public StateOp {
-public:
- SetupPaintFilterOp(int clearBits, int setBits)
- : mClearBits(clearBits), mSetBits(setBits) {}
-
- virtual void applyState(OpenGLRenderer& renderer, int saveCount) const {
- renderer.setupPaintFilter(mClearBits, mSetBits);
- }
-
- virtual void output(int level, uint32_t logFlags) const {
- OP_LOG("SetupPaintFilter, clear %#x, set %#x", mClearBits, mSetBits);
- }
-
- virtual const char* name() { return "SetupPaintFilter"; }
-
-private:
- int mClearBits;
- int mSetBits;
-};
-
///////////////////////////////////////////////////////////////////////////////
// DRAW OPERATIONS - these are operations that can draw to the canvas's device
///////////////////////////////////////////////////////////////////////////////
@@ -655,8 +619,8 @@
}
}
- virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty) {
- return renderer.drawBitmap(mBitmap, getPaint(renderer));
+ virtual void applyDraw(OpenGLRenderer& renderer, Rect& dirty) {
+ renderer.drawBitmap(mBitmap, mPaint);
}
AssetAtlas::Entry* getAtlasEntry() {
@@ -678,7 +642,7 @@
* for each bitmap in the batch. This method is also responsible for dirtying
* the current layer, if any.
*/
- virtual status_t multiDraw(OpenGLRenderer& renderer, Rect& dirty,
+ virtual void multiDraw(OpenGLRenderer& renderer, Rect& dirty,
const Vector<OpStatePair>& ops, const Rect& bounds) {
const DeferredDisplayState& firstState = *(ops[0].state);
renderer.restoreDisplayState(firstState, true); // restore all but the clip
@@ -715,7 +679,7 @@
}
}
- return renderer.drawBitmaps(mBitmap, mEntry, ops.size(), &vertices[0],
+ renderer.drawBitmaps(mBitmap, mEntry, ops.size(), &vertices[0],
pureTranslate, bounds, mPaint);
}
@@ -758,10 +722,10 @@
: DrawBoundedOp(dstLeft, dstTop, dstRight, dstBottom, paint),
mBitmap(bitmap), mSrc(srcLeft, srcTop, srcRight, srcBottom) {}
- virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty) {
- return renderer.drawBitmap(mBitmap, mSrc.left, mSrc.top, mSrc.right, mSrc.bottom,
+ virtual void applyDraw(OpenGLRenderer& renderer, Rect& dirty) {
+ renderer.drawBitmap(mBitmap, mSrc.left, mSrc.top, mSrc.right, mSrc.bottom,
mLocalBounds.left, mLocalBounds.top, mLocalBounds.right, mLocalBounds.bottom,
- getPaint(renderer));
+ mPaint);
}
virtual void output(int level, uint32_t logFlags) const {
@@ -786,8 +750,8 @@
DrawBitmapDataOp(const SkBitmap* bitmap, const SkPaint* paint)
: DrawBitmapOp(bitmap, paint) {}
- virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty) {
- return renderer.drawBitmapData(mBitmap, getPaint(renderer));
+ virtual void applyDraw(OpenGLRenderer& renderer, Rect& dirty) {
+ renderer.drawBitmapData(mBitmap, mPaint);
}
virtual void output(int level, uint32_t logFlags) const {
@@ -810,9 +774,9 @@
mBitmap(bitmap), mMeshWidth(meshWidth), mMeshHeight(meshHeight),
mVertices(vertices), mColors(colors) {}
- virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty) {
- return renderer.drawBitmapMesh(mBitmap, mMeshWidth, mMeshHeight,
- mVertices, mColors, getPaint(renderer));
+ virtual void applyDraw(OpenGLRenderer& renderer, Rect& dirty) {
+ renderer.drawBitmapMesh(mBitmap, mMeshWidth, mMeshHeight,
+ mVertices, mColors, mPaint);
}
virtual void output(int level, uint32_t logFlags) const {
@@ -871,7 +835,7 @@
* and transforming the vertices of each 9-patch in the batch. This method
* is also responsible for dirtying the current layer, if any.
*/
- virtual status_t multiDraw(OpenGLRenderer& renderer, Rect& dirty,
+ virtual void multiDraw(OpenGLRenderer& renderer, Rect& dirty,
const Vector<OpStatePair>& ops, const Rect& bounds) {
const DeferredDisplayState& firstState = *(ops[0].state);
renderer.restoreDisplayState(firstState, true); // restore all but the clip
@@ -941,16 +905,16 @@
indexCount += opMesh->indexCount;
}
- return renderer.drawPatches(mBitmap, getAtlasEntry(),
- &vertices[0], indexCount, getPaint(renderer));
+ renderer.drawPatches(mBitmap, getAtlasEntry(),
+ &vertices[0], indexCount, mPaint);
}
- virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty) {
+ virtual void applyDraw(OpenGLRenderer& renderer, Rect& dirty) {
// We're not calling the public variant of drawPatch() here
// This method won't perform the quickReject() since we've already done it at this point
- return renderer.drawPatch(mBitmap, getMesh(renderer), getAtlasEntry(),
+ renderer.drawPatch(mBitmap, getMesh(renderer), getAtlasEntry(),
mLocalBounds.left, mLocalBounds.top, mLocalBounds.right, mLocalBounds.bottom,
- getPaint(renderer));
+ mPaint);
}
virtual void output(int level, uint32_t logFlags) const {
@@ -985,8 +949,8 @@
DrawColorOp(int color, SkXfermode::Mode mode)
: DrawOp(NULL), mColor(color), mMode(mode) {};
- virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty) {
- return renderer.drawColor(mColor, mMode);
+ virtual void applyDraw(OpenGLRenderer& renderer, Rect& dirty) {
+ renderer.drawColor(mColor, mMode);
}
virtual void output(int level, uint32_t logFlags) const {
@@ -1032,9 +996,9 @@
DrawRectOp(float left, float top, float right, float bottom, const SkPaint* paint)
: DrawStrokableOp(left, top, right, bottom, paint) {}
- virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty) {
- return renderer.drawRect(mLocalBounds.left, mLocalBounds.top,
- mLocalBounds.right, mLocalBounds.bottom, getPaint(renderer));
+ virtual void applyDraw(OpenGLRenderer& renderer, Rect& dirty) {
+ renderer.drawRect(mLocalBounds.left, mLocalBounds.top,
+ mLocalBounds.right, mLocalBounds.bottom, mPaint);
}
virtual void output(int level, uint32_t logFlags) const {
@@ -1057,8 +1021,8 @@
: DrawBoundedOp(rects, count, paint),
mRects(rects), mCount(count) {}
- virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty) {
- return renderer.drawRects(mRects, mCount, getPaint(renderer));
+ virtual void applyDraw(OpenGLRenderer& renderer, Rect& dirty) {
+ renderer.drawRects(mRects, mCount, mPaint);
}
virtual void output(int level, uint32_t logFlags) const {
@@ -1083,9 +1047,9 @@
float rx, float ry, const SkPaint* paint)
: DrawStrokableOp(left, top, right, bottom, paint), mRx(rx), mRy(ry) {}
- virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty) {
- return renderer.drawRoundRect(mLocalBounds.left, mLocalBounds.top,
- mLocalBounds.right, mLocalBounds.bottom, mRx, mRy, getPaint(renderer));
+ virtual void applyDraw(OpenGLRenderer& renderer, Rect& dirty) {
+ renderer.drawRoundRect(mLocalBounds.left, mLocalBounds.top,
+ mLocalBounds.right, mLocalBounds.bottom, mRx, mRy, mPaint);
}
virtual void output(int level, uint32_t logFlags) const {
@@ -1115,9 +1079,9 @@
: DrawOp(paint), mLeft(left), mTop(top), mRight(right), mBottom(bottom),
mRx(rx), mRy(ry) {}
- virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty) {
- return renderer.drawRoundRect(*mLeft, *mTop, *mRight, *mBottom,
- *mRx, *mRy, getPaint(renderer));
+ virtual void applyDraw(OpenGLRenderer& renderer, Rect& dirty) {
+ renderer.drawRoundRect(*mLeft, *mTop, *mRight, *mBottom,
+ *mRx, *mRy, mPaint);
}
virtual void output(int level, uint32_t logFlags) const {
@@ -1142,8 +1106,8 @@
: DrawStrokableOp(x - radius, y - radius, x + radius, y + radius, paint),
mX(x), mY(y), mRadius(radius) {}
- virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty) {
- return renderer.drawCircle(mX, mY, mRadius, getPaint(renderer));
+ virtual void applyDraw(OpenGLRenderer& renderer, Rect& dirty) {
+ renderer.drawCircle(mX, mY, mRadius, mPaint);
}
virtual void output(int level, uint32_t logFlags) const {
@@ -1163,8 +1127,8 @@
DrawCirclePropsOp(float* x, float* y, float* radius, const SkPaint* paint)
: DrawOp(paint), mX(x), mY(y), mRadius(radius) {}
- virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty) {
- return renderer.drawCircle(*mX, *mY, *mRadius, getPaint(renderer));
+ virtual void applyDraw(OpenGLRenderer& renderer, Rect& dirty) {
+ renderer.drawCircle(*mX, *mY, *mRadius, mPaint);
}
virtual void output(int level, uint32_t logFlags) const {
@@ -1184,9 +1148,9 @@
DrawOvalOp(float left, float top, float right, float bottom, const SkPaint* paint)
: DrawStrokableOp(left, top, right, bottom, paint) {}
- virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty) {
- return renderer.drawOval(mLocalBounds.left, mLocalBounds.top,
- mLocalBounds.right, mLocalBounds.bottom, getPaint(renderer));
+ virtual void applyDraw(OpenGLRenderer& renderer, Rect& dirty) {
+ renderer.drawOval(mLocalBounds.left, mLocalBounds.top,
+ mLocalBounds.right, mLocalBounds.bottom, mPaint);
}
virtual void output(int level, uint32_t logFlags) const {
@@ -1203,10 +1167,10 @@
: DrawStrokableOp(left, top, right, bottom, paint),
mStartAngle(startAngle), mSweepAngle(sweepAngle), mUseCenter(useCenter) {}
- virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty) {
- return renderer.drawArc(mLocalBounds.left, mLocalBounds.top,
+ virtual void applyDraw(OpenGLRenderer& renderer, Rect& dirty) {
+ renderer.drawArc(mLocalBounds.left, mLocalBounds.top,
mLocalBounds.right, mLocalBounds.bottom,
- mStartAngle, mSweepAngle, mUseCenter, getPaint(renderer));
+ mStartAngle, mSweepAngle, mUseCenter, mPaint);
}
virtual void output(int level, uint32_t logFlags) const {
@@ -1234,14 +1198,13 @@
mLocalBounds.set(left, top, left + width, top + height);
}
- virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty) {
- return renderer.drawPath(mPath, getPaint(renderer));
+ virtual void applyDraw(OpenGLRenderer& renderer, Rect& dirty) {
+ renderer.drawPath(mPath, mPaint);
}
virtual void onDefer(OpenGLRenderer& renderer, DeferInfo& deferInfo,
const DeferredDisplayState& state) {
- const SkPaint* paint = getPaint(renderer);
- renderer.getCaches().pathCache.precache(mPath, paint);
+ renderer.getCaches().pathCache.precache(mPath, mPaint);
deferInfo.batchId = DeferredDisplayList::kOpBatch_AlphaMaskTexture;
}
@@ -1264,8 +1227,8 @@
mLocalBounds.outset(strokeWidthOutset());
}
- virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty) {
- return renderer.drawLines(mPoints, mCount, getPaint(renderer));
+ virtual void applyDraw(OpenGLRenderer& renderer, Rect& dirty) {
+ renderer.drawLines(mPoints, mCount, mPaint);
}
virtual void output(int level, uint32_t logFlags) const {
@@ -1291,8 +1254,8 @@
DrawPointsOp(const float* points, int count, const SkPaint* paint)
: DrawLinesOp(points, count, paint) {}
- virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty) {
- return renderer.drawPoints(mPoints, mCount, getPaint(renderer));
+ virtual void applyDraw(OpenGLRenderer& renderer, Rect& dirty) {
+ renderer.drawPoints(mPoints, mCount, mPaint);
}
virtual void output(int level, uint32_t logFlags) const {
@@ -1317,9 +1280,8 @@
virtual void onDefer(OpenGLRenderer& renderer, DeferInfo& deferInfo,
const DeferredDisplayState& state) {
- const SkPaint* paint = getPaint(renderer);
- FontRenderer& fontRenderer = renderer.getCaches().fontRenderer->getFontRenderer(paint);
- fontRenderer.precache(paint, mText, mCount, SkMatrix::I());
+ FontRenderer& fontRenderer = renderer.getCaches().fontRenderer->getFontRenderer(mPaint);
+ fontRenderer.precache(mPaint, mText, mCount, SkMatrix::I());
deferInfo.batchId = mPaint->getColor() == SK_ColorBLACK ?
DeferredDisplayList::kOpBatch_Text :
@@ -1341,9 +1303,9 @@
/* TODO: inherit from DrawBounded and init mLocalBounds */
}
- virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty) {
- return renderer.drawTextOnPath(mText, mBytesCount, mCount, mPath,
- mHOffset, mVOffset, getPaint(renderer));
+ virtual void applyDraw(OpenGLRenderer& renderer, Rect& dirty) {
+ renderer.drawTextOnPath(mText, mBytesCount, mCount, mPath,
+ mHOffset, mVOffset, mPaint);
}
virtual const char* name() { return "DrawTextOnPath"; }
@@ -1362,8 +1324,8 @@
/* TODO: inherit from DrawBounded and init mLocalBounds */
}
- virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty) {
- return renderer.drawPosText(mText, mBytesCount, mCount, mPositions, getPaint(renderer));
+ virtual void applyDraw(OpenGLRenderer& renderer, Rect& dirty) {
+ renderer.drawPosText(mText, mBytesCount, mCount, mPositions, mPaint);
}
virtual const char* name() { return "DrawPosText"; }
@@ -1383,12 +1345,11 @@
virtual void onDefer(OpenGLRenderer& renderer, DeferInfo& deferInfo,
const DeferredDisplayState& state) {
- const SkPaint* paint = getPaint(renderer);
- FontRenderer& fontRenderer = renderer.getCaches().fontRenderer->getFontRenderer(paint);
+ FontRenderer& fontRenderer = renderer.getCaches().fontRenderer->getFontRenderer(mPaint);
SkMatrix transform;
renderer.findBestFontTransform(state.mMatrix, &transform);
if (mPrecacheTransform != transform) {
- fontRenderer.precache(paint, mText, mCount, transform);
+ fontRenderer.precache(mPaint, mText, mCount, transform);
mPrecacheTransform = transform;
}
deferInfo.batchId = mPaint->getColor() == SK_ColorBLACK ?
@@ -1406,16 +1367,15 @@
&& OpenGLRenderer::getXfermodeDirect(mPaint) == SkXfermode::kSrcOver_Mode;
}
- virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty) {
+ virtual void applyDraw(OpenGLRenderer& renderer, Rect& dirty) {
Rect bounds;
getLocalBounds(bounds);
- return renderer.drawText(mText, mBytesCount, mCount, mX, mY,
- mPositions, getPaint(renderer), mTotalAdvance, bounds);
+ renderer.drawText(mText, mBytesCount, mCount, mX, mY,
+ mPositions, mPaint, mTotalAdvance, bounds);
}
- virtual status_t multiDraw(OpenGLRenderer& renderer, Rect& dirty,
+ virtual void multiDraw(OpenGLRenderer& renderer, Rect& dirty,
const Vector<OpStatePair>& ops, const Rect& bounds) {
- status_t status = DrawGlInfo::kStatusDone;
for (unsigned int i = 0; i < ops.size(); i++) {
const DeferredDisplayState& state = *(ops[i].state);
DrawOpMode drawOpMode = (i == ops.size() - 1) ? kDrawOpMode_Flush : kDrawOpMode_Defer;
@@ -1424,11 +1384,10 @@
DrawTextOp& op = *((DrawTextOp*)ops[i].op);
// quickReject() will not occure in drawText() so we can use mLocalBounds
// directly, we do not need to account for shadow by calling getLocalBounds()
- status |= renderer.drawText(op.mText, op.mBytesCount, op.mCount, op.mX, op.mY,
- op.mPositions, op.getPaint(renderer), op.mTotalAdvance, op.mLocalBounds,
+ renderer.drawText(op.mText, op.mBytesCount, op.mCount, op.mX, op.mY,
+ op.mPositions, op.mPaint, op.mTotalAdvance, op.mLocalBounds,
drawOpMode);
}
- return status;
}
virtual void output(int level, uint32_t logFlags) const {
@@ -1457,11 +1416,10 @@
DrawFunctorOp(Functor* functor)
: DrawOp(NULL), mFunctor(functor) {}
- virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty) {
+ virtual void applyDraw(OpenGLRenderer& renderer, Rect& dirty) {
renderer.startMark("GL functor");
- status_t ret = renderer.callDrawGLFunction(mFunctor, dirty);
+ renderer.callDrawGLFunction(mFunctor, dirty);
renderer.endMark();
- return ret;
}
virtual void output(int level, uint32_t logFlags) const {
@@ -1496,9 +1454,8 @@
}
}
- virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty) {
+ virtual void applyDraw(OpenGLRenderer& renderer, Rect& dirty) {
LOG_ALWAYS_FATAL("should not be called, because replay() is overridden");
- return 0;
}
virtual void output(int level, uint32_t logFlags) const {
@@ -1557,7 +1514,7 @@
&mTransformXY, &mTransformZ, renderer.getLightCenter(), renderer.getLightRadius());
}
- virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty) {
+ virtual void applyDraw(OpenGLRenderer& renderer, Rect& dirty) {
TessellationCache::vertexBuffer_pair_t buffers;
Matrix4 drawTransform(*(renderer.currentTransform()));
renderer.getCaches().tessellationCache.getShadowBuffers(&drawTransform,
@@ -1565,7 +1522,7 @@
&mTransformXY, &mTransformZ, renderer.getLightCenter(), renderer.getLightRadius(),
buffers);
- return renderer.drawShadow(mCasterAlpha, buffers.first, buffers.second);
+ renderer.drawShadow(mCasterAlpha, buffers.first, buffers.second);
}
virtual void output(int level, uint32_t logFlags) const {
@@ -1588,8 +1545,8 @@
DrawLayerOp(Layer* layer, float x, float y)
: DrawOp(NULL), mLayer(layer), mX(x), mY(y) {}
- virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty) {
- return renderer.drawLayer(mLayer, mX, mY);
+ virtual void applyDraw(OpenGLRenderer& renderer, Rect& dirty) {
+ renderer.drawLayer(mLayer, mX, mY);
}
virtual void output(int level, uint32_t logFlags) const {
diff --git a/libs/hwui/DisplayListRenderer.cpp b/libs/hwui/DisplayListRenderer.cpp
index c2cb76e..8887aa7 100644
--- a/libs/hwui/DisplayListRenderer.cpp
+++ b/libs/hwui/DisplayListRenderer.cpp
@@ -33,7 +33,8 @@
namespace uirenderer {
DisplayListRenderer::DisplayListRenderer()
- : mResourceCache(ResourceCache::getInstance())
+ : mState(*this)
+ , mResourceCache(ResourceCache::getInstance())
, mDisplayListData(NULL)
, mTranslateX(0.0f)
, mTranslateY(0.0f)
@@ -60,25 +61,24 @@
return data;
}
-status_t DisplayListRenderer::prepareDirty(float left, float top,
+void DisplayListRenderer::prepareDirty(float left, float top,
float right, float bottom, bool opaque) {
LOG_ALWAYS_FATAL_IF(mDisplayListData,
"prepareDirty called a second time during a recording!");
mDisplayListData = new DisplayListData();
- initializeSaveStack(0, 0, getWidth(), getHeight(), Vector3());
+ mState.initializeSaveStack(0, 0, mState.getWidth(), mState.getHeight(), Vector3());
mDeferredBarrierType = kBarrier_InOrder;
- mDirtyClip = opaque;
+ mState.setDirtyClip(opaque);
mRestoreSaveCount = -1;
-
- return DrawGlInfo::kStatusDone; // No invalidate needed at record-time
}
-void DisplayListRenderer::finish() {
+bool DisplayListRenderer::finish() {
flushRestoreToCount();
flushTranslate();
+ return false;
}
void DisplayListRenderer::interrupt() {
@@ -87,16 +87,15 @@
void DisplayListRenderer::resume() {
}
-status_t DisplayListRenderer::callDrawGLFunction(Functor *functor, Rect& dirty) {
+void DisplayListRenderer::callDrawGLFunction(Functor *functor, Rect& dirty) {
// Ignore dirty during recording, it matters only when we replay
addDrawOp(new (alloc()) DrawFunctorOp(functor));
mDisplayListData->functors.add(functor);
- return DrawGlInfo::kStatusDone; // No invalidate needed at record-time
}
int DisplayListRenderer::save(int flags) {
addStateOp(new (alloc()) SaveOp(flags));
- return StatefulBaseRenderer::save(flags);
+ return mState.save(flags);
}
void DisplayListRenderer::restore() {
@@ -107,13 +106,13 @@
mRestoreSaveCount--;
flushTranslate();
- StatefulBaseRenderer::restore();
+ mState.restore();
}
void DisplayListRenderer::restoreToCount(int saveCount) {
mRestoreSaveCount = saveCount;
flushTranslate();
- StatefulBaseRenderer::restoreToCount(saveCount);
+ mState.restoreToCount(saveCount);
}
int DisplayListRenderer::saveLayer(float left, float top, float right, float bottom,
@@ -123,7 +122,7 @@
paint = refPaint(paint);
addStateOp(new (alloc()) SaveLayerOp(left, top, right, bottom, paint, flags));
- return StatefulBaseRenderer::save(flags);
+ return mState.save(flags);
}
void DisplayListRenderer::translate(float dx, float dy, float dz) {
@@ -132,80 +131,76 @@
mTranslateX += dx;
mTranslateY += dy;
flushRestoreToCount();
- StatefulBaseRenderer::translate(dx, dy, dz);
+ mState.translate(dx, dy, dz);
}
void DisplayListRenderer::rotate(float degrees) {
addStateOp(new (alloc()) RotateOp(degrees));
- StatefulBaseRenderer::rotate(degrees);
+ mState.rotate(degrees);
}
void DisplayListRenderer::scale(float sx, float sy) {
addStateOp(new (alloc()) ScaleOp(sx, sy));
- StatefulBaseRenderer::scale(sx, sy);
+ mState.scale(sx, sy);
}
void DisplayListRenderer::skew(float sx, float sy) {
addStateOp(new (alloc()) SkewOp(sx, sy));
- StatefulBaseRenderer::skew(sx, sy);
+ mState.skew(sx, sy);
}
void DisplayListRenderer::setMatrix(const SkMatrix& matrix) {
addStateOp(new (alloc()) SetMatrixOp(matrix));
- StatefulBaseRenderer::setMatrix(matrix);
+ mState.setMatrix(matrix);
}
void DisplayListRenderer::concatMatrix(const SkMatrix& matrix) {
addStateOp(new (alloc()) ConcatMatrixOp(matrix));
- StatefulBaseRenderer::concatMatrix(matrix);
+ mState.concatMatrix(matrix);
}
bool DisplayListRenderer::clipRect(float left, float top, float right, float bottom,
SkRegion::Op op) {
addStateOp(new (alloc()) ClipRectOp(left, top, right, bottom, op));
- return StatefulBaseRenderer::clipRect(left, top, right, bottom, op);
+ return mState.clipRect(left, top, right, bottom, op);
}
bool DisplayListRenderer::clipPath(const SkPath* path, SkRegion::Op op) {
path = refPath(path);
addStateOp(new (alloc()) ClipPathOp(path, op));
- return StatefulBaseRenderer::clipPath(path, op);
+ return mState.clipPath(path, op);
}
bool DisplayListRenderer::clipRegion(const SkRegion* region, SkRegion::Op op) {
region = refRegion(region);
addStateOp(new (alloc()) ClipRegionOp(region, op));
- return StatefulBaseRenderer::clipRegion(region, op);
+ return mState.clipRegion(region, op);
}
-status_t DisplayListRenderer::drawRenderNode(RenderNode* renderNode, Rect& dirty, int32_t flags) {
+void DisplayListRenderer::drawRenderNode(RenderNode* renderNode, Rect& dirty, int32_t flags) {
LOG_ALWAYS_FATAL_IF(!renderNode, "missing rendernode");
// dirty is an out parameter and should not be recorded,
// it matters only when replaying the display list
- DrawRenderNodeOp* op = new (alloc()) DrawRenderNodeOp(renderNode, flags, *currentTransform());
+ DrawRenderNodeOp* op = new (alloc()) DrawRenderNodeOp(renderNode, flags, *mState.currentTransform());
addRenderNodeOp(op);
-
- return DrawGlInfo::kStatusDone;
}
-status_t DisplayListRenderer::drawLayer(DeferredLayerUpdater* layerHandle, float x, float y) {
+void DisplayListRenderer::drawLayer(DeferredLayerUpdater* layerHandle, float x, float y) {
// We ref the DeferredLayerUpdater due to its thread-safe ref-counting
// semantics.
mDisplayListData->ref(layerHandle);
addDrawOp(new (alloc()) DrawLayerOp(layerHandle->backingLayer(), x, y));
- return DrawGlInfo::kStatusDone;
}
-status_t DisplayListRenderer::drawBitmap(const SkBitmap* bitmap, const SkPaint* paint) {
+void DisplayListRenderer::drawBitmap(const SkBitmap* bitmap, const SkPaint* paint) {
bitmap = refBitmap(bitmap);
paint = refPaint(paint);
addDrawOp(new (alloc()) DrawBitmapOp(bitmap, paint));
- return DrawGlInfo::kStatusDone;
}
-status_t DisplayListRenderer::drawBitmap(const SkBitmap* bitmap, float srcLeft, float srcTop,
+void DisplayListRenderer::drawBitmap(const SkBitmap* bitmap, float srcLeft, float srcTop,
float srcRight, float srcBottom, float dstLeft, float dstTop,
float dstRight, float dstBottom, const SkPaint* paint) {
if (srcLeft == 0 && srcTop == 0
@@ -225,18 +220,16 @@
srcLeft, srcTop, srcRight, srcBottom,
dstLeft, dstTop, dstRight, dstBottom, paint));
}
- return DrawGlInfo::kStatusDone;
}
-status_t DisplayListRenderer::drawBitmapData(const SkBitmap* bitmap, const SkPaint* paint) {
+void DisplayListRenderer::drawBitmapData(const SkBitmap* bitmap, const SkPaint* paint) {
bitmap = refBitmapData(bitmap);
paint = refPaint(paint);
addDrawOp(new (alloc()) DrawBitmapDataOp(bitmap, paint));
- return DrawGlInfo::kStatusDone;
}
-status_t DisplayListRenderer::drawBitmapMesh(const SkBitmap* bitmap, int meshWidth, int meshHeight,
+void DisplayListRenderer::drawBitmapMesh(const SkBitmap* bitmap, int meshWidth, int meshHeight,
const float* vertices, const int* colors, const SkPaint* paint) {
int vertexCount = (meshWidth + 1) * (meshHeight + 1);
bitmap = refBitmap(bitmap);
@@ -246,39 +239,34 @@
addDrawOp(new (alloc()) DrawBitmapMeshOp(bitmap, meshWidth, meshHeight,
vertices, colors, paint));
- return DrawGlInfo::kStatusDone;
}
-status_t DisplayListRenderer::drawPatch(const SkBitmap* bitmap, const Res_png_9patch* patch,
+void DisplayListRenderer::drawPatch(const SkBitmap* bitmap, const Res_png_9patch* patch,
float left, float top, float right, float bottom, const SkPaint* paint) {
bitmap = refBitmap(bitmap);
patch = refPatch(patch);
paint = refPaint(paint);
addDrawOp(new (alloc()) DrawPatchOp(bitmap, patch, left, top, right, bottom, paint));
- return DrawGlInfo::kStatusDone;
}
-status_t DisplayListRenderer::drawColor(int color, SkXfermode::Mode mode) {
+void DisplayListRenderer::drawColor(int color, SkXfermode::Mode mode) {
addDrawOp(new (alloc()) DrawColorOp(color, mode));
- return DrawGlInfo::kStatusDone;
}
-status_t DisplayListRenderer::drawRect(float left, float top, float right, float bottom,
+void DisplayListRenderer::drawRect(float left, float top, float right, float bottom,
const SkPaint* paint) {
paint = refPaint(paint);
addDrawOp(new (alloc()) DrawRectOp(left, top, right, bottom, paint));
- return DrawGlInfo::kStatusDone;
}
-status_t DisplayListRenderer::drawRoundRect(float left, float top, float right, float bottom,
+void DisplayListRenderer::drawRoundRect(float left, float top, float right, float bottom,
float rx, float ry, const SkPaint* paint) {
paint = refPaint(paint);
addDrawOp(new (alloc()) DrawRoundRectOp(left, top, right, bottom, rx, ry, paint));
- return DrawGlInfo::kStatusDone;
}
-status_t DisplayListRenderer::drawRoundRect(
+void DisplayListRenderer::drawRoundRect(
CanvasPropertyPrimitive* left, CanvasPropertyPrimitive* top,
CanvasPropertyPrimitive* right, CanvasPropertyPrimitive* bottom,
CanvasPropertyPrimitive* rx, CanvasPropertyPrimitive* ry,
@@ -292,16 +280,14 @@
mDisplayListData->ref(paint);
addDrawOp(new (alloc()) DrawRoundRectPropsOp(&left->value, &top->value,
&right->value, &bottom->value, &rx->value, &ry->value, &paint->value));
- return DrawGlInfo::kStatusDone;
}
-status_t DisplayListRenderer::drawCircle(float x, float y, float radius, const SkPaint* paint) {
+void DisplayListRenderer::drawCircle(float x, float y, float radius, const SkPaint* paint) {
paint = refPaint(paint);
addDrawOp(new (alloc()) DrawCircleOp(x, y, radius, paint));
- return DrawGlInfo::kStatusDone;
}
-status_t DisplayListRenderer::drawCircle(CanvasPropertyPrimitive* x, CanvasPropertyPrimitive* y,
+void DisplayListRenderer::drawCircle(CanvasPropertyPrimitive* x, CanvasPropertyPrimitive* y,
CanvasPropertyPrimitive* radius, CanvasPropertyPaint* paint) {
mDisplayListData->ref(x);
mDisplayListData->ref(y);
@@ -309,55 +295,49 @@
mDisplayListData->ref(paint);
addDrawOp(new (alloc()) DrawCirclePropsOp(&x->value, &y->value,
&radius->value, &paint->value));
- return DrawGlInfo::kStatusDone;
}
-status_t DisplayListRenderer::drawOval(float left, float top, float right, float bottom,
+void DisplayListRenderer::drawOval(float left, float top, float right, float bottom,
const SkPaint* paint) {
paint = refPaint(paint);
addDrawOp(new (alloc()) DrawOvalOp(left, top, right, bottom, paint));
- return DrawGlInfo::kStatusDone;
}
-status_t DisplayListRenderer::drawArc(float left, float top, float right, float bottom,
+void DisplayListRenderer::drawArc(float left, float top, float right, float bottom,
float startAngle, float sweepAngle, bool useCenter, const SkPaint* paint) {
if (fabs(sweepAngle) >= 360.0f) {
- return drawOval(left, top, right, bottom, paint);
+ drawOval(left, top, right, bottom, paint);
+ } else {
+ paint = refPaint(paint);
+ addDrawOp(new (alloc()) DrawArcOp(left, top, right, bottom,
+ startAngle, sweepAngle, useCenter, paint));
}
-
- paint = refPaint(paint);
- addDrawOp(new (alloc()) DrawArcOp(left, top, right, bottom,
- startAngle, sweepAngle, useCenter, paint));
- return DrawGlInfo::kStatusDone;
}
-status_t DisplayListRenderer::drawPath(const SkPath* path, const SkPaint* paint) {
+void DisplayListRenderer::drawPath(const SkPath* path, const SkPaint* paint) {
path = refPath(path);
paint = refPaint(paint);
addDrawOp(new (alloc()) DrawPathOp(path, paint));
- return DrawGlInfo::kStatusDone;
}
-status_t DisplayListRenderer::drawLines(const float* points, int count, const SkPaint* paint) {
+void DisplayListRenderer::drawLines(const float* points, int count, const SkPaint* paint) {
points = refBuffer<float>(points, count);
paint = refPaint(paint);
addDrawOp(new (alloc()) DrawLinesOp(points, count, paint));
- return DrawGlInfo::kStatusDone;
}
-status_t DisplayListRenderer::drawPoints(const float* points, int count, const SkPaint* paint) {
+void DisplayListRenderer::drawPoints(const float* points, int count, const SkPaint* paint) {
points = refBuffer<float>(points, count);
paint = refPaint(paint);
addDrawOp(new (alloc()) DrawPointsOp(points, count, paint));
- return DrawGlInfo::kStatusDone;
}
-status_t DisplayListRenderer::drawTextOnPath(const char* text, int bytesCount, int count,
+void DisplayListRenderer::drawTextOnPath(const char* text, int bytesCount, int count,
const SkPath* path, float hOffset, float vOffset, const SkPaint* paint) {
- if (!text || count <= 0) return DrawGlInfo::kStatusDone;
+ if (!text || count <= 0) return;
text = refText(text, bytesCount);
path = refPath(path);
@@ -366,12 +346,11 @@
DrawOp* op = new (alloc()) DrawTextOnPathOp(text, bytesCount, count, path,
hOffset, vOffset, paint);
addDrawOp(op);
- return DrawGlInfo::kStatusDone;
}
-status_t DisplayListRenderer::drawPosText(const char* text, int bytesCount, int count,
+void DisplayListRenderer::drawPosText(const char* text, int bytesCount, int count,
const float* positions, const SkPaint* paint) {
- if (!text || count <= 0) return DrawGlInfo::kStatusDone;
+ if (!text || count <= 0) return;
text = refText(text, bytesCount);
positions = refBuffer<float>(positions, count * 2);
@@ -379,7 +358,6 @@
DrawOp* op = new (alloc()) DrawPosTextOp(text, bytesCount, count, positions, paint);
addDrawOp(op);
- return DrawGlInfo::kStatusDone;
}
static void simplifyPaint(int color, SkPaint* paint) {
@@ -392,11 +370,11 @@
paint->setLooper(NULL);
}
-status_t DisplayListRenderer::drawText(const char* text, int bytesCount, int count,
+void DisplayListRenderer::drawText(const char* text, int bytesCount, int count,
float x, float y, const float* positions, const SkPaint* paint,
float totalAdvance, const Rect& bounds, DrawOpMode drawOpMode) {
- if (!text || count <= 0 || paintWillNotDrawText(*paint)) return DrawGlInfo::kStatusDone;
+ if (!text || count <= 0 || paintWillNotDrawText(*paint)) return;
text = refText(text, bytesCount);
positions = refBuffer<float>(positions, count * 2);
@@ -428,24 +406,18 @@
x, y, positions, paint, totalAdvance, bounds);
addDrawOp(op);
}
- return DrawGlInfo::kStatusDone;
}
-status_t DisplayListRenderer::drawRects(const float* rects, int count, const SkPaint* paint) {
- if (count <= 0) return DrawGlInfo::kStatusDone;
+void DisplayListRenderer::drawRects(const float* rects, int count, const SkPaint* paint) {
+ if (count <= 0) return;
rects = refBuffer<float>(rects, count);
paint = refPaint(paint);
addDrawOp(new (alloc()) DrawRectsOp(rects, count, paint));
- return DrawGlInfo::kStatusDone;
}
-void DisplayListRenderer::resetPaintFilter() {
- addStateOp(new (alloc()) ResetPaintFilterOp());
-}
-
-void DisplayListRenderer::setupPaintFilter(int clearBits, int setBits) {
- addStateOp(new (alloc()) SetupPaintFilterOp(clearBits, setBits));
+void DisplayListRenderer::setDrawFilter(SkDrawFilter* filter) {
+ mDrawFilter.reset(filter);
}
void DisplayListRenderer::insertReorderBarrier(bool enableReorder) {
diff --git a/libs/hwui/DisplayListRenderer.h b/libs/hwui/DisplayListRenderer.h
index 2cc2be3..6646da7 100644
--- a/libs/hwui/DisplayListRenderer.h
+++ b/libs/hwui/DisplayListRenderer.h
@@ -17,13 +17,19 @@
#ifndef ANDROID_HWUI_DISPLAY_LIST_RENDERER_H
#define ANDROID_HWUI_DISPLAY_LIST_RENDERER_H
+#include <SkDrawFilter.h>
#include <SkMatrix.h>
#include <SkPaint.h>
#include <SkPath.h>
+#include <SkRegion.h>
+#include <SkTLazy.h>
#include <cutils/compiler.h>
+#include "CanvasState.h"
+#include "DisplayList.h"
#include "DisplayListLogBuffer.h"
#include "RenderNode.h"
+#include "Renderer.h"
#include "ResourceCache.h"
namespace android {
@@ -48,13 +54,15 @@
class DeferredLayerUpdater;
class DisplayListRenderer;
class DisplayListOp;
+class DisplayListRenderer;
class DrawOp;
+class RenderNode;
class StateOp;
/**
* Records drawing commands in a display list for later playback into an OpenGLRenderer.
*/
-class ANDROID_API DisplayListRenderer: public StatefulBaseRenderer {
+class ANDROID_API DisplayListRenderer: public Renderer, public CanvasStateClient {
public:
DisplayListRenderer();
virtual ~DisplayListRenderer();
@@ -66,15 +74,21 @@
// ----------------------------------------------------------------------------
// Frame state operations
// ----------------------------------------------------------------------------
- virtual status_t prepareDirty(float left, float top, float right, float bottom, bool opaque);
- virtual void finish();
+ virtual void prepareDirty(float left, float top, float right, float bottom, bool opaque);
+ virtual void prepare(bool opaque) {
+ prepareDirty(0.0f, 0.0f, mState.getWidth(), mState.getHeight(), opaque);
+ }
+ virtual bool finish();
virtual void interrupt();
virtual void resume();
// ----------------------------------------------------------------------------
// Canvas state operations
// ----------------------------------------------------------------------------
+ virtual void setViewport(int width, int height) { mState.setViewport(width, height); }
+
// Save (layer)
+ virtual int getSaveCount() const { return mState.getSaveCount(); }
virtual int save(int flags);
virtual void restore();
virtual void restoreToCount(int saveCount);
@@ -82,6 +96,8 @@
const SkPaint* paint, int flags);
// Matrix
+ virtual void getMatrix(SkMatrix* outMatrix) const { mState.getMatrix(outMatrix); }
+
virtual void translate(float dx, float dy, float dz = 0.0f);
virtual void rotate(float degrees);
virtual void scale(float sx, float sy);
@@ -95,73 +111,88 @@
virtual bool clipPath(const SkPath* path, SkRegion::Op op);
virtual bool clipRegion(const SkRegion* region, SkRegion::Op op);
- // Misc - should be implemented with SkPaint inspection
- virtual void resetPaintFilter();
- virtual void setupPaintFilter(int clearBits, int setBits);
+ // Misc
+ virtual void setDrawFilter(SkDrawFilter* filter);
+ virtual const Rect& getLocalClipBounds() const { return mState.getLocalClipBounds(); }
+ const Rect& getRenderTargetClipBounds() const { return mState.getRenderTargetClipBounds(); }
+ virtual bool quickRejectConservative(float left, float top, float right, float bottom) const {
+ return mState.quickRejectConservative(left, top, right, bottom);
+ }
bool isCurrentTransformSimple() {
- return currentTransform()->isSimple();
+ return mState.currentTransform()->isSimple();
}
// ----------------------------------------------------------------------------
// Canvas draw operations
// ----------------------------------------------------------------------------
- virtual status_t drawColor(int color, SkXfermode::Mode mode);
+ virtual void drawColor(int color, SkXfermode::Mode mode);
// Bitmap-based
- virtual status_t drawBitmap(const SkBitmap* bitmap, const SkPaint* paint);
- virtual status_t drawBitmap(const SkBitmap* bitmap, float srcLeft, float srcTop,
+ virtual void drawBitmap(const SkBitmap* bitmap, const SkPaint* paint);
+ virtual void drawBitmap(const SkBitmap* bitmap, float srcLeft, float srcTop,
float srcRight, float srcBottom, float dstLeft, float dstTop,
float dstRight, float dstBottom, const SkPaint* paint);
- virtual status_t drawBitmapData(const SkBitmap* bitmap, const SkPaint* paint);
- virtual status_t drawBitmapMesh(const SkBitmap* bitmap, int meshWidth, int meshHeight,
+ virtual void drawBitmapData(const SkBitmap* bitmap, const SkPaint* paint);
+ virtual void drawBitmapMesh(const SkBitmap* bitmap, int meshWidth, int meshHeight,
const float* vertices, const int* colors, const SkPaint* paint);
- virtual status_t drawPatch(const SkBitmap* bitmap, const Res_png_9patch* patch,
+ virtual void drawPatch(const SkBitmap* bitmap, const Res_png_9patch* patch,
float left, float top, float right, float bottom, const SkPaint* paint);
// Shapes
- virtual status_t drawRect(float left, float top, float right, float bottom,
+ virtual void drawRect(float left, float top, float right, float bottom,
const SkPaint* paint);
- virtual status_t drawRects(const float* rects, int count, const SkPaint* paint);
- virtual status_t drawRoundRect(float left, float top, float right, float bottom,
+ virtual void drawRects(const float* rects, int count, const SkPaint* paint);
+ virtual void drawRoundRect(float left, float top, float right, float bottom,
float rx, float ry, const SkPaint* paint);
- virtual status_t drawRoundRect(CanvasPropertyPrimitive* left, CanvasPropertyPrimitive* top,
+ virtual void drawRoundRect(CanvasPropertyPrimitive* left, CanvasPropertyPrimitive* top,
CanvasPropertyPrimitive* right, CanvasPropertyPrimitive* bottom,
CanvasPropertyPrimitive* rx, CanvasPropertyPrimitive* ry,
CanvasPropertyPaint* paint);
- virtual status_t drawCircle(float x, float y, float radius, const SkPaint* paint);
- virtual status_t drawCircle(CanvasPropertyPrimitive* x, CanvasPropertyPrimitive* y,
+ virtual void drawCircle(float x, float y, float radius, const SkPaint* paint);
+ virtual void drawCircle(CanvasPropertyPrimitive* x, CanvasPropertyPrimitive* y,
CanvasPropertyPrimitive* radius, CanvasPropertyPaint* paint);
- virtual status_t drawOval(float left, float top, float right, float bottom,
+ virtual void drawOval(float left, float top, float right, float bottom,
const SkPaint* paint);
- virtual status_t drawArc(float left, float top, float right, float bottom,
+ virtual void drawArc(float left, float top, float right, float bottom,
float startAngle, float sweepAngle, bool useCenter, const SkPaint* paint);
- virtual status_t drawPath(const SkPath* path, const SkPaint* paint);
- virtual status_t drawLines(const float* points, int count, const SkPaint* paint);
- virtual status_t drawPoints(const float* points, int count, const SkPaint* paint);
+ virtual void drawPath(const SkPath* path, const SkPaint* paint);
+ virtual void drawLines(const float* points, int count, const SkPaint* paint);
+ virtual void drawPoints(const float* points, int count, const SkPaint* paint);
// Text
- virtual status_t drawText(const char* text, int bytesCount, int count, float x, float y,
+ virtual void drawText(const char* text, int bytesCount, int count, float x, float y,
const float* positions, const SkPaint* paint, float totalAdvance, const Rect& bounds,
DrawOpMode drawOpMode = kDrawOpMode_Immediate);
- virtual status_t drawTextOnPath(const char* text, int bytesCount, int count, const SkPath* path,
+ virtual void drawTextOnPath(const char* text, int bytesCount, int count, const SkPath* path,
float hOffset, float vOffset, const SkPaint* paint);
- virtual status_t drawPosText(const char* text, int bytesCount, int count,
+ virtual void drawPosText(const char* text, int bytesCount, int count,
const float* positions, const SkPaint* paint);
// ----------------------------------------------------------------------------
// Canvas draw operations - special
// ----------------------------------------------------------------------------
- virtual status_t drawLayer(DeferredLayerUpdater* layerHandle, float x, float y);
- virtual status_t drawRenderNode(RenderNode* renderNode, Rect& dirty, int32_t replayFlags);
+ virtual void drawLayer(DeferredLayerUpdater* layerHandle, float x, float y);
+ virtual void drawRenderNode(RenderNode* renderNode, Rect& dirty, int32_t replayFlags);
// TODO: rename for consistency
- virtual status_t callDrawGLFunction(Functor* functor, Rect& dirty);
+ virtual void callDrawGLFunction(Functor* functor, Rect& dirty);
void setHighContrastText(bool highContrastText) {
mHighContrastText = highContrastText;
}
+
+// ----------------------------------------------------------------------------
+// CanvasState callbacks
+// ----------------------------------------------------------------------------
+ virtual void onViewportInitialized() { }
+ virtual void onSnapshotRestored(const Snapshot& removed, const Snapshot& restored) { }
+ virtual GLuint onGetTargetFbo() const { return -1; }
+
private:
+
+ CanvasState mState;
+
enum DeferredBarrierType {
kBarrier_None,
kBarrier_InOrder,
@@ -220,35 +251,34 @@
inline const SkPaint* refPaint(const SkPaint* paint) {
if (!paint) return NULL;
- const SkPaint* paintCopy = mPaintMap.valueFor(paint);
- if (paintCopy == NULL
- || paintCopy->getGenerationID() != paint->getGenerationID()
- // We can't compare shader pointers because that will always
- // change as we do partial copying via wrapping. However, if the
- // shader changes the paint generationID will have changed and
- // so we don't hit this comparison anyway
- || !(paint->getShader() && paintCopy->getShader()
- && paint->getShader()->getGenerationID() == paintCopy->getShader()->getGenerationID())) {
- paintCopy = copyPaint(paint);
- // replaceValueFor() performs an add if the entry doesn't exist
- mPaintMap.replaceValueFor(paint, paintCopy);
+ // If there is a draw filter apply it here and store the modified paint
+ // so that we don't need to modify the paint every time we access it.
+ SkTLazy<SkPaint> filteredPaint;
+ if (mDrawFilter.get()) {
+ paint = filteredPaint.init();
+ mDrawFilter->filter(filteredPaint.get(), SkDrawFilter::kPaint_Type);
}
- return paintCopy;
+ // compute the hash key for the paint and check the cache.
+ const uint32_t key = paint->getHash();
+ const SkPaint* cachedPaint = mPaintMap.valueFor(key);
+ // In the unlikely event that 2 unique paints have the same hash we do a
+ // object equality check to ensure we don't erroneously dedup them.
+ if (cachedPaint == NULL || *cachedPaint != *paint) {
+ cachedPaint = new SkPaint(*paint);
+ // replaceValueFor() performs an add if the entry doesn't exist
+ mPaintMap.replaceValueFor(key, cachedPaint);
+ mDisplayListData->paints.add(cachedPaint);
+ }
+
+ return cachedPaint;
}
inline SkPaint* copyPaint(const SkPaint* paint) {
if (!paint) return NULL;
SkPaint* paintCopy = new SkPaint(*paint);
- if (paint->getShader()) {
- SkShader* shaderCopy = SkShader::CreateLocalMatrixShader(
- paint->getShader(), paint->getShader()->getLocalMatrix());
- paintCopy->setShader(shaderCopy);
- paintCopy->setGenerationID(paint->getGenerationID());
- shaderCopy->setGenerationID(paint->getShader()->getGenerationID());
- shaderCopy->unref();
- }
mDisplayListData->paints.add(paintCopy);
+
return paintCopy;
}
@@ -291,7 +321,7 @@
return patch;
}
- DefaultKeyedVector<const SkPaint*, const SkPaint*> mPaintMap;
+ DefaultKeyedVector<uint32_t, const SkPaint*> mPaintMap;
DefaultKeyedVector<const SkPath*, const SkPath*> mPathMap;
DefaultKeyedVector<const SkRegion*, const SkRegion*> mRegionMap;
@@ -306,6 +336,8 @@
int mRestoreSaveCount;
+ SkAutoTUnref<SkDrawFilter> mDrawFilter;
+
friend class RenderNode;
}; // class DisplayListRenderer
diff --git a/libs/hwui/Dither.h b/libs/hwui/Dither.h
index 546236be..092ebf2 100644
--- a/libs/hwui/Dither.h
+++ b/libs/hwui/Dither.h
@@ -19,12 +19,11 @@
#include <GLES3/gl3.h>
-#include "Program.h"
-
namespace android {
namespace uirenderer {
class Caches;
+class Program;
// Must be a power of two
#define DITHER_KERNEL_SIZE 4
diff --git a/libs/hwui/FontRenderer.h b/libs/hwui/FontRenderer.h
index 5c96c6b4..e11128c 100644
--- a/libs/hwui/FontRenderer.h
+++ b/libs/hwui/FontRenderer.h
@@ -31,8 +31,6 @@
#include "font/CachedGlyphInfo.h"
#include "font/Font.h"
#include "utils/SortedList.h"
-#include "Matrix.h"
-#include "Properties.h"
#ifdef ANDROID_ENABLE_RENDERSCRIPT
#include "RenderScript.h"
diff --git a/libs/hwui/GradientCache.h b/libs/hwui/GradientCache.h
index 6a783b1..c94b6f0 100644
--- a/libs/hwui/GradientCache.h
+++ b/libs/hwui/GradientCache.h
@@ -25,11 +25,11 @@
#include <utils/Mutex.h>
#include <utils/Vector.h>
-#include "Texture.h"
-
namespace android {
namespace uirenderer {
+class Texture;
+
struct GradientCacheEntry {
GradientCacheEntry() {
count = 0;
diff --git a/libs/hwui/Layer.h b/libs/hwui/Layer.h
index 64d1d12..3b909d5 100644
--- a/libs/hwui/Layer.h
+++ b/libs/hwui/Layer.h
@@ -20,6 +20,7 @@
#include <cutils/compiler.h>
#include <sys/types.h>
#include <utils/StrongPointer.h>
+#include <utils/RefBase.h>
#include <GLES2/gl2.h>
@@ -47,7 +48,7 @@
class OpenGLRenderer;
class RenderNode;
class DeferredDisplayList;
-class DeferStateStruct;
+struct DeferStateStruct;
/**
* A layer has dimensions and is backed by an OpenGL texture or FBO.
diff --git a/libs/hwui/LayerRenderer.cpp b/libs/hwui/LayerRenderer.cpp
index 394c647..268b9da 100644
--- a/libs/hwui/LayerRenderer.cpp
+++ b/libs/hwui/LayerRenderer.cpp
@@ -43,7 +43,7 @@
LayerRenderer::~LayerRenderer() {
}
-status_t LayerRenderer::prepareDirty(float left, float top, float right, float bottom,
+void LayerRenderer::prepareDirty(float left, float top, float right, float bottom,
bool opaque) {
LAYER_RENDERER_LOGD("Rendering into layer, fbo = %d", mLayer->getFbo());
@@ -64,25 +64,23 @@
}
mLayer->clipRect.set(dirty);
- return OpenGLRenderer::prepareDirty(dirty.left, dirty.top, dirty.right, dirty.bottom, opaque);
+ OpenGLRenderer::prepareDirty(dirty.left, dirty.top, dirty.right, dirty.bottom, opaque);
}
-status_t LayerRenderer::clear(float left, float top, float right, float bottom, bool opaque) {
+void LayerRenderer::clear(float left, float top, float right, float bottom, bool opaque) {
if (mLayer->isDirty()) {
getCaches().disableScissor();
glClear(GL_COLOR_BUFFER_BIT);
getCaches().resetScissor();
mLayer->setDirty(false);
-
- return DrawGlInfo::kStatusDone;
+ } else {
+ OpenGLRenderer::clear(left, top, right, bottom, opaque);
}
-
- return OpenGLRenderer::clear(left, top, right, bottom, opaque);
}
-void LayerRenderer::finish() {
- OpenGLRenderer::finish();
+bool LayerRenderer::finish() {
+ bool retval = OpenGLRenderer::finish();
generateMesh();
@@ -90,9 +88,10 @@
// No need to unbind our FBO, this will be taken care of by the caller
// who will invoke OpenGLRenderer::resume()
+ return retval;
}
-GLuint LayerRenderer::getTargetFbo() const {
+GLuint LayerRenderer::onGetTargetFbo() const {
return mLayer->getFbo();
}
@@ -117,7 +116,7 @@
///////////////////////////////////////////////////////////////////////////////
Region* LayerRenderer::getRegion() const {
- if (currentSnapshot()->flags & Snapshot::kFlagFboTarget) {
+ if (mState.currentFlags() & Snapshot::kFlagFboTarget) {
return OpenGLRenderer::getRegion();
}
return &mLayer->region;
diff --git a/libs/hwui/LayerRenderer.h b/libs/hwui/LayerRenderer.h
index 4d8620b..769ef49 100644
--- a/libs/hwui/LayerRenderer.h
+++ b/libs/hwui/LayerRenderer.h
@@ -50,9 +50,9 @@
virtual ~LayerRenderer();
virtual void onViewportInitialized() { /* do nothing */ }
- virtual status_t prepareDirty(float left, float top, float right, float bottom, bool opaque);
- virtual status_t clear(float left, float top, float right, float bottom, bool opaque);
- virtual void finish();
+ virtual void prepareDirty(float left, float top, float right, float bottom, bool opaque);
+ virtual void clear(float left, float top, float right, float bottom, bool opaque);
+ virtual bool finish();
static Layer* createTextureLayer(RenderState& renderState);
static Layer* createRenderLayer(RenderState& renderState, uint32_t width, uint32_t height);
@@ -68,7 +68,7 @@
virtual void ensureStencilBuffer();
virtual bool hasLayer() const;
virtual Region* getRegion() const;
- virtual GLuint getTargetFbo() const;
+ virtual GLuint onGetTargetFbo() const;
virtual bool suppressErrorChecks() const;
private:
diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp
index d570b0d..71b7c11 100755
--- a/libs/hwui/OpenGLRenderer.cpp
+++ b/libs/hwui/OpenGLRenderer.cpp
@@ -36,14 +36,17 @@
#include "DeferredDisplayList.h"
#include "DisplayListRenderer.h"
#include "Fence.h"
-#include "RenderState.h"
+#include "GammaFontRenderer.h"
+#include "Patch.h"
#include "PathTessellator.h"
#include "Properties.h"
+#include "RenderNode.h"
+#include "RenderState.h"
#include "ShadowTessellator.h"
#include "SkiaShader.h"
-#include "utils/GLUtils.h"
#include "Vector.h"
#include "VertexBuffer.h"
+#include "utils/GLUtils.h"
#if DEBUG_DETAILED_EVENTS
#define EVENT_LOGD(...) eventMarkDEBUG(__VA_ARGS__)
@@ -144,13 +147,15 @@
///////////////////////////////////////////////////////////////////////////////
OpenGLRenderer::OpenGLRenderer(RenderState& renderState)
- : mFrameStarted(false)
+ : mState(*this)
+ , mFrameStarted(false)
, mCaches(Caches::getInstance())
, mExtensions(Extensions::getInstance())
, mRenderState(renderState)
, mScissorOptimizationDisabled(false)
, mSuppressTiling(false)
, mFirstFrameAfterResize(true)
+ , mDirty(false)
, mLightCenter((Vector3){FLT_MIN, FLT_MIN, FLT_MIN})
, mLightRadius(FLT_MIN)
, mAmbientShadowAlpha(0)
@@ -201,20 +206,20 @@
void OpenGLRenderer::setupFrameState(float left, float top,
float right, float bottom, bool opaque) {
mCaches.clearGarbage();
- initializeSaveStack(left, top, right, bottom, mLightCenter);
+ mState.initializeSaveStack(left, top, right, bottom, mLightCenter);
mOpaque = opaque;
mTilingClip.set(left, top, right, bottom);
}
-status_t OpenGLRenderer::startFrame() {
- if (mFrameStarted) return DrawGlInfo::kStatusDone;
+void OpenGLRenderer::startFrame() {
+ if (mFrameStarted) return;
mFrameStarted = true;
- mDirtyClip = true;
+ mState.setDirtyClip(true);
discardFramebuffer(mTilingClip.left, mTilingClip.top, mTilingClip.right, mTilingClip.bottom);
- mRenderState.setViewport(getWidth(), getHeight());
+ mRenderState.setViewport(mState.getWidth(), mState.getHeight());
// Functors break the tiling extension in pretty spectacular ways
// This ensures we don't use tiling when a functor is going to be
@@ -227,11 +232,11 @@
debugOverdraw(true, true);
- return clear(mTilingClip.left, mTilingClip.top,
+ clear(mTilingClip.left, mTilingClip.top,
mTilingClip.right, mTilingClip.bottom, mOpaque);
}
-status_t OpenGLRenderer::prepareDirty(float left, float top,
+void OpenGLRenderer::prepareDirty(float left, float top,
float right, float bottom, bool opaque) {
setupFrameState(left, top, right, bottom, opaque);
@@ -244,10 +249,8 @@
syncState();
updateLayers();
} else {
- return startFrame();
+ startFrame();
}
-
- return DrawGlInfo::kStatusDone;
}
void OpenGLRenderer::discardFramebuffer(float left, float top, float right, float bottom) {
@@ -255,8 +258,8 @@
// perform a discard to let the driver know we don't need to preserve
// the back buffer for this frame.
if (mExtensions.hasDiscardFramebuffer() &&
- left <= 0.0f && top <= 0.0f && right >= getWidth() && bottom >= getHeight()) {
- const bool isFbo = getTargetFbo() == 0;
+ left <= 0.0f && top <= 0.0f && right >= mState.getWidth() && bottom >= mState.getHeight()) {
+ const bool isFbo = onGetTargetFbo() == 0;
const GLenum attachments[] = {
isFbo ? (const GLenum) GL_COLOR_EXT : (const GLenum) GL_COLOR_ATTACHMENT0,
isFbo ? (const GLenum) GL_STENCIL_EXT : (const GLenum) GL_STENCIL_ATTACHMENT };
@@ -264,16 +267,16 @@
}
}
-status_t OpenGLRenderer::clear(float left, float top, float right, float bottom, bool opaque) {
+void OpenGLRenderer::clear(float left, float top, float right, float bottom, bool opaque) {
if (!opaque) {
mCaches.enableScissor();
mCaches.setScissor(left, getViewportHeight() - bottom, right - left, bottom - top);
glClear(GL_COLOR_BUFFER_BIT);
- return DrawGlInfo::kStatusDrew;
+ mDirty = true;
+ return;
}
mCaches.resetScissor();
- return DrawGlInfo::kStatusDone;
}
void OpenGLRenderer::syncState() {
@@ -321,13 +324,13 @@
if (!mSuppressTiling) mCaches.endTiling();
}
-void OpenGLRenderer::finish() {
+bool OpenGLRenderer::finish() {
renderOverdraw();
endTiling();
// When finish() is invoked on FBO 0 we've reached the end
// of the current frame
- if (getTargetFbo() == 0) {
+ if (onGetTargetFbo() == 0) {
mCaches.pathCache.trim();
mCaches.tessellationCache.trim();
}
@@ -347,6 +350,8 @@
}
mFrameStarted = false;
+
+ return reportAndClearDirty();
}
void OpenGLRenderer::resumeAfterLayer() {
@@ -358,10 +363,10 @@
dirtyClip();
}
-status_t OpenGLRenderer::callDrawGLFunction(Functor* functor, Rect& dirty) {
- if (currentSnapshot()->isIgnored()) return DrawGlInfo::kStatusDone;
+void OpenGLRenderer::callDrawGLFunction(Functor* functor, Rect& dirty) {
+ if (mState.currentlyIgnored()) return;
- Rect clip(*currentClipRect());
+ Rect clip(*mState.currentClipRect());
clip.snapToPixelBoundaries();
// Since we don't know what the functor will draw, let's dirty
@@ -380,9 +385,9 @@
info.height = getViewportHeight();
currentTransform()->copyTo(&info.transform[0]);
- bool prevDirtyClip = mDirtyClip;
+ bool prevDirtyClip = mState.getDirtyClip();
// setup GL state for functor
- if (mDirtyClip) {
+ if (mState.getDirtyClip()) {
setStencilFromClip(); // can issue draws, so must precede enableScissor()/interrupt()
}
if (mCaches.enableScissor() || prevDirtyClip) {
@@ -393,7 +398,7 @@
// Scissor may have been modified, reset dirty clip
dirtyClip();
- return DrawGlInfo::kStatusDrew;
+ mDirty = true;
}
///////////////////////////////////////////////////////////////////////////////
@@ -432,11 +437,11 @@
}
void OpenGLRenderer::renderOverdraw() {
- if (mCaches.debugOverdraw && getTargetFbo() == 0) {
+ if (mCaches.debugOverdraw && onGetTargetFbo() == 0) {
const Rect* clip = &mTilingClip;
mCaches.enableScissor();
- mCaches.setScissor(clip->left, firstSnapshot()->getViewportHeight() - clip->bottom,
+ mCaches.setScissor(clip->left, mState.firstSnapshot()->getViewportHeight() - clip->bottom,
clip->right - clip->left, clip->bottom - clip->top);
// 1x overdraw
@@ -515,7 +520,7 @@
if (CC_UNLIKELY(mCaches.drawDeferDisabled)) {
mLayerUpdates.clear();
- mRenderState.bindFramebuffer(getTargetFbo());
+ mRenderState.bindFramebuffer(onGetTargetFbo());
}
endMark();
}
@@ -542,7 +547,7 @@
}
mLayerUpdates.clear();
- mRenderState.bindFramebuffer(getTargetFbo());
+ mRenderState.bindFramebuffer(onGetTargetFbo());
endMark();
}
@@ -624,9 +629,9 @@
// force matrix/clip isolation for layer
flags |= SkCanvas::kClip_SaveFlag | SkCanvas::kMatrix_SaveFlag;
- const int count = saveSnapshot(flags);
+ const int count = mState.saveSnapshot(flags);
- if (!currentSnapshot()->isIgnored()) {
+ if (!mState.currentlyIgnored()) {
createLayer(left, top, right, bottom, paint, flags, convexMask);
}
@@ -639,7 +644,7 @@
currentTransform()->mapRect(bounds);
// Layers only make sense if they are in the framebuffer's bounds
- if (bounds.intersect(*currentClipRect())) {
+ if (bounds.intersect(*mState.currentClipRect())) {
// We cannot work with sub-pixels in this case
bounds.snapToPixelBoundaries();
@@ -673,17 +678,17 @@
if (bounds.isEmpty() || bounds.getWidth() > mCaches.maxTextureSize ||
bounds.getHeight() > mCaches.maxTextureSize ||
(fboLayer && clip.isEmpty())) {
- mSnapshot->empty = fboLayer;
+ writableSnapshot()->empty = fboLayer;
} else {
- mSnapshot->invisible = mSnapshot->invisible || (alpha <= 0 && fboLayer);
+ writableSnapshot()->invisible = writableSnapshot()->invisible || (alpha <= 0 && fboLayer);
}
}
int OpenGLRenderer::saveLayerDeferred(float left, float top, float right, float bottom,
const SkPaint* paint, int flags) {
- const int count = saveSnapshot(flags);
+ const int count = mState.saveSnapshot(flags);
- if (!currentSnapshot()->isIgnored() && (flags & SkCanvas::kClipToLayer_SaveFlag)) {
+ if (!mState.currentlyIgnored() && (flags & SkCanvas::kClipToLayer_SaveFlag)) {
// initialize the snapshot as though it almost represents an FBO layer so deferred draw
// operations will be able to store and restore the current clip and transform info, and
// quick rejection will be correct (for display lists)
@@ -693,11 +698,11 @@
calculateLayerBoundsAndClip(bounds, clip, true);
updateSnapshotIgnoreForLayer(bounds, clip, true, getAlphaDirect(paint));
- if (!currentSnapshot()->isIgnored()) {
- mSnapshot->resetTransform(-bounds.left, -bounds.top, 0.0f);
- mSnapshot->resetClip(clip.left, clip.top, clip.right, clip.bottom);
- mSnapshot->initializeViewport(bounds.getWidth(), bounds.getHeight());
- mSnapshot->roundRectClipState = NULL;
+ if (!mState.currentlyIgnored()) {
+ writableSnapshot()->resetTransform(-bounds.left, -bounds.top, 0.0f);
+ writableSnapshot()->resetClip(clip.left, clip.top, clip.right, clip.bottom);
+ writableSnapshot()->initializeViewport(bounds.getWidth(), bounds.getHeight());
+ writableSnapshot()->roundRectClipState = NULL;
}
}
@@ -769,7 +774,7 @@
updateSnapshotIgnoreForLayer(bounds, clip, fboLayer, getAlphaDirect(paint));
// Bail out if we won't draw in this snapshot
- if (currentSnapshot()->isIgnored()) {
+ if (mState.currentlyIgnored()) {
return false;
}
@@ -789,8 +794,8 @@
layer->setConvexMask(convexMask); // note: the mask must be cleared before returning to the cache
// Save the layer in the snapshot
- mSnapshot->flags |= Snapshot::kFlagIsLayer;
- mSnapshot->layer = layer;
+ writableSnapshot()->flags |= Snapshot::kFlagIsLayer;
+ writableSnapshot()->layer = layer;
ATRACE_FORMAT_BEGIN("%ssaveLayer %ux%u",
fboLayer ? "" : "unclipped ",
@@ -828,13 +833,13 @@
layer->clipRect.set(clip);
layer->setFbo(mCaches.fboCache.get());
- mSnapshot->region = &mSnapshot->layer->region;
- mSnapshot->flags |= Snapshot::kFlagFboTarget | Snapshot::kFlagIsFboLayer;
- mSnapshot->fbo = layer->getFbo();
- mSnapshot->resetTransform(-bounds.left, -bounds.top, 0.0f);
- mSnapshot->resetClip(clip.left, clip.top, clip.right, clip.bottom);
- mSnapshot->initializeViewport(bounds.getWidth(), bounds.getHeight());
- mSnapshot->roundRectClipState = NULL;
+ writableSnapshot()->region = &writableSnapshot()->layer->region;
+ writableSnapshot()->flags |= Snapshot::kFlagFboTarget | Snapshot::kFlagIsFboLayer;
+ writableSnapshot()->fbo = layer->getFbo();
+ writableSnapshot()->resetTransform(-bounds.left, -bounds.top, 0.0f);
+ writableSnapshot()->resetClip(clip.left, clip.top, clip.right, clip.bottom);
+ writableSnapshot()->initializeViewport(bounds.getWidth(), bounds.getHeight());
+ writableSnapshot()->roundRectClipState = NULL;
endTiling();
debugOverdraw(false, false);
@@ -881,7 +886,7 @@
const bool fboLayer = removed.flags & Snapshot::kFlagIsFboLayer;
bool clipRequired = false;
- calculateQuickRejectForScissor(rect.left, rect.top, rect.right, rect.bottom,
+ mState.calculateQuickRejectForScissor(rect.left, rect.top, rect.right, rect.bottom,
&clipRequired, NULL, false); // safely ignore return, should never be rejected
mCaches.setScissorEnabled(mScissorOptimizationDisabled || clipRequired);
@@ -926,7 +931,7 @@
save(0);
// the layer contains screen buffer content that shouldn't be alpha modulated
// (and any necessary alpha modulation was handled drawing into the layer)
- mSnapshot->alpha = 1.0f;
+ writableSnapshot()->alpha = 1.0f;
composeLayerRect(layer, rect, true);
restore();
}
@@ -1034,13 +1039,13 @@
* operations are correctly counted twice for overdraw. NOTE: assumes composeLayerRegion only used
* by saveLayer's restore
*/
-#define DRAW_DOUBLE_STENCIL_IF(COND, DRAW_COMMAND) { \
- DRAW_COMMAND; \
- if (CC_UNLIKELY(mCaches.debugOverdraw && getTargetFbo() == 0 && COND)) { \
- glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); \
- DRAW_COMMAND; \
- glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); \
- } \
+#define DRAW_DOUBLE_STENCIL_IF(COND, DRAW_COMMAND) { \
+ DRAW_COMMAND; \
+ if (CC_UNLIKELY(mCaches.debugOverdraw && onGetTargetFbo() == 0 && COND)) { \
+ glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); \
+ DRAW_COMMAND; \
+ glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); \
+ } \
}
#define DRAW_DOUBLE_STENCIL(DRAW_COMMAND) DRAW_DOUBLE_STENCIL_IF(true, DRAW_COMMAND)
@@ -1269,7 +1274,7 @@
}
void OpenGLRenderer::dirtyLayerUnchecked(Rect& bounds, Region* region) {
- if (bounds.intersect(*currentClipRect())) {
+ if (bounds.intersect(*mState.currentClipRect())) {
bounds.snapToPixelBoundaries();
android::Rect dirty(bounds.left, bounds.top, bounds.right, bounds.bottom);
if (!dirty.isEmpty()) {
@@ -1297,7 +1302,7 @@
const size_t count = mLayers.size();
if (count == 0) return;
- if (!currentSnapshot()->isIgnored()) {
+ if (!mState.currentlyIgnored()) {
EVENT_LOGD("clearLayerRegions");
// Doing several glScissor/glClear here can negatively impact
// GPUs with a tiler architecture, instead we draw quads with
@@ -1353,7 +1358,7 @@
///////////////////////////////////////////////////////////////////////////////
bool OpenGLRenderer::storeDisplayState(DeferredDisplayState& state, int stateDeferFlags) {
- const Rect* currentClip = currentClipRect();
+ const Rect* currentClip = mState.currentClipRect();
const mat4* currentMatrix = currentTransform();
if (stateDeferFlags & kStateDeferFlag_Draw) {
@@ -1406,12 +1411,12 @@
void OpenGLRenderer::restoreDisplayState(const DeferredDisplayState& state, bool skipClipRestore) {
setMatrix(state.mMatrix);
- mSnapshot->alpha = state.mAlpha;
+ writableSnapshot()->alpha = state.mAlpha;
mDrawModifiers = state.mDrawModifiers;
- mSnapshot->roundRectClipState = state.mRoundRectClipState;
+ writableSnapshot()->roundRectClipState = state.mRoundRectClipState;
if (state.mClipValid && !skipClipRestore) {
- mSnapshot->setClip(state.mClip.left, state.mClip.top,
+ writableSnapshot()->setClip(state.mClip.left, state.mClip.top,
state.mClip.right, state.mClip.bottom);
dirtyClip();
}
@@ -1426,9 +1431,9 @@
*/
void OpenGLRenderer::setupMergedMultiDraw(const Rect* clipRect) {
if (clipRect != NULL) {
- mSnapshot->setClip(clipRect->left, clipRect->top, clipRect->right, clipRect->bottom);
+ writableSnapshot()->setClip(clipRect->left, clipRect->top, clipRect->right, clipRect->bottom);
} else {
- mSnapshot->setClip(0, 0, getWidth(), getHeight());
+ writableSnapshot()->setClip(0, 0, mState.getWidth(), mState.getHeight());
}
dirtyClip();
mCaches.setScissorEnabled(clipRect != NULL || mScissorOptimizationDisabled);
@@ -1439,12 +1444,12 @@
///////////////////////////////////////////////////////////////////////////////
void OpenGLRenderer::setScissorFromClip() {
- Rect clip(*currentClipRect());
+ Rect clip(*mState.currentClipRect());
clip.snapToPixelBoundaries();
if (mCaches.setScissor(clip.left, getViewportHeight() - clip.bottom,
clip.getWidth(), clip.getHeight())) {
- mDirtyClip = false;
+ mState.setDirtyClip(false);
}
}
@@ -1480,7 +1485,7 @@
// NOTE: The order here is important, we must set dirtyClip to false
// before any draw call to avoid calling back into this method
- mDirtyClip = false;
+ mState.setDirtyClip(false);
ensureStencilBuffer();
@@ -1549,7 +1554,7 @@
bool clipRequired = false;
bool roundRectClipRequired = false;
- if (calculateQuickRejectForScissor(left, top, right, bottom,
+ if (mState.calculateQuickRejectForScissor(left, top, right, bottom,
&clipRequired, &roundRectClipRequired, snapOut)) {
return true;
}
@@ -1581,7 +1586,7 @@
if (clearLayer) clearLayerRegions();
// Make sure setScissor & setStencil happen at the beginning of
// this method
- if (mDirtyClip) {
+ if (mState.getDirtyClip()) {
if (mCaches.scissorEnabled) {
setScissorFromClip();
}
@@ -1719,7 +1724,7 @@
useProgram(mCaches.programCache.get(mDescription));
if (mDescription.hasRoundRectClip) {
// TODO: avoid doing this repeatedly, stashing state pointer in program
- const RoundRectClipState* state = mSnapshot->roundRectClipState;
+ const RoundRectClipState* state = writableSnapshot()->roundRectClipState;
const Rect& innerRect = state->innerRect;
glUniform4f(mCaches.currentProgram->getUniform("roundRectInnerRectLTRB"),
innerRect.left, innerRect.top,
@@ -1747,7 +1752,7 @@
bool dirty = right - left > 0.0f && bottom - top > 0.0f;
const Matrix4& transformMatrix = ignoreTransform ? Matrix4::identity() : *currentTransform();
- mCaches.currentProgram->set(mSnapshot->getOrthoMatrix(), mModelViewMatrix, transformMatrix, offset);
+ mCaches.currentProgram->set(writableSnapshot()->getOrthoMatrix(), mModelViewMatrix, transformMatrix, offset);
if (dirty && mTrackDirtyRegions) {
if (!ignoreTransform) {
dirtyLayer(left, top, right, bottom, *currentTransform());
@@ -1925,33 +1930,32 @@
// Drawing
///////////////////////////////////////////////////////////////////////////////
-status_t OpenGLRenderer::drawRenderNode(RenderNode* renderNode, Rect& dirty, int32_t replayFlags) {
- status_t status;
+void OpenGLRenderer::drawRenderNode(RenderNode* renderNode, Rect& dirty, int32_t replayFlags) {
// All the usual checks and setup operations (quickReject, setupDraw, etc.)
// will be performed by the display list itself
if (renderNode && renderNode->isRenderable()) {
// compute 3d ordering
renderNode->computeOrdering();
if (CC_UNLIKELY(mCaches.drawDeferDisabled)) {
- status = startFrame();
+ startFrame();
ReplayStateStruct replayStruct(*this, dirty, replayFlags);
renderNode->replay(replayStruct, 0);
- return status | replayStruct.mDrawGlStatus;
+ return;
}
- DeferredDisplayList deferredList(*currentClipRect());
+ DeferredDisplayList deferredList(*mState.currentClipRect());
DeferStateStruct deferStruct(deferredList, *this, replayFlags);
renderNode->defer(deferStruct, 0);
flushLayers();
- status = startFrame();
+ startFrame();
- return deferredList.flush(*this, dirty) | status;
+ deferredList.flush(*this, dirty);
+ } else {
+ // Even if there is no drawing command(Ex: invisible),
+ // it still needs startFrame to clear buffer and start tiling.
+ startFrame();
}
-
- // Even if there is no drawing command(Ex: invisible),
- // it still needs startFrame to clear buffer and start tiling.
- return startFrame();
}
void OpenGLRenderer::drawAlphaBitmap(Texture* texture, float left, float top, const SkPaint* paint) {
@@ -1985,12 +1989,12 @@
* will not set the scissor enable or dirty the current layer, if any.
* The caller is responsible for properly dirtying the current layer.
*/
-status_t OpenGLRenderer::drawBitmaps(const SkBitmap* bitmap, AssetAtlas::Entry* entry,
+void OpenGLRenderer::drawBitmaps(const SkBitmap* bitmap, AssetAtlas::Entry* entry,
int bitmapCount, TextureVertex* vertices, bool pureTranslate,
const Rect& bounds, const SkPaint* paint) {
mCaches.activeTexture(0);
Texture* texture = entry ? entry->texture : mCaches.textureCache.get(bitmap);
- if (!texture) return DrawGlInfo::kStatusDone;
+ if (!texture) return;
const AutoTexture autoCleanup(texture);
@@ -2011,17 +2015,17 @@
kModelViewMode_Translate, false);
}
- return DrawGlInfo::kStatusDrew;
+ mDirty = true;
}
-status_t OpenGLRenderer::drawBitmap(const SkBitmap* bitmap, const SkPaint* paint) {
+void OpenGLRenderer::drawBitmap(const SkBitmap* bitmap, const SkPaint* paint) {
if (quickRejectSetupScissor(0, 0, bitmap->width(), bitmap->height())) {
- return DrawGlInfo::kStatusDone;
+ return;
}
mCaches.activeTexture(0);
Texture* texture = getTexture(bitmap);
- if (!texture) return DrawGlInfo::kStatusDone;
+ if (!texture) return;
const AutoTexture autoCleanup(texture);
if (CC_UNLIKELY(bitmap->colorType() == kAlpha_8_SkColorType)) {
@@ -2030,12 +2034,12 @@
drawTextureRect(0, 0, bitmap->width(), bitmap->height(), texture, paint);
}
- return DrawGlInfo::kStatusDrew;
+ mDirty = true;
}
-status_t OpenGLRenderer::drawBitmapData(const SkBitmap* bitmap, const SkPaint* paint) {
+void OpenGLRenderer::drawBitmapData(const SkBitmap* bitmap, const SkPaint* paint) {
if (quickRejectSetupScissor(0, 0, bitmap->width(), bitmap->height())) {
- return DrawGlInfo::kStatusDone;
+ return;
}
mCaches.activeTexture(0);
@@ -2048,13 +2052,13 @@
drawTextureRect(0, 0, bitmap->width(), bitmap->height(), texture, paint);
}
- return DrawGlInfo::kStatusDrew;
+ mDirty = true;
}
-status_t OpenGLRenderer::drawBitmapMesh(const SkBitmap* bitmap, int meshWidth, int meshHeight,
+void OpenGLRenderer::drawBitmapMesh(const SkBitmap* bitmap, int meshWidth, int meshHeight,
const float* vertices, const int* colors, const SkPaint* paint) {
- if (!vertices || currentSnapshot()->isIgnored()) {
- return DrawGlInfo::kStatusDone;
+ if (!vertices || mState.currentlyIgnored()) {
+ return;
}
// TODO: use quickReject on bounds from vertices
@@ -2121,14 +2125,14 @@
if (quickRejectSetupScissor(left, top, right, bottom)) {
if (cleanupColors) delete[] colors;
- return DrawGlInfo::kStatusDone;
+ return;
}
if (!texture) {
texture = mCaches.textureCache.get(bitmap);
if (!texture) {
if (cleanupColors) delete[] colors;
- return DrawGlInfo::kStatusDone;
+ return;
}
}
const AutoTexture autoCleanup(texture);
@@ -2168,20 +2172,20 @@
if (cleanupColors) delete[] colors;
- return DrawGlInfo::kStatusDrew;
+ mDirty = true;
}
-status_t OpenGLRenderer::drawBitmap(const SkBitmap* bitmap,
+void OpenGLRenderer::drawBitmap(const SkBitmap* bitmap,
float srcLeft, float srcTop, float srcRight, float srcBottom,
float dstLeft, float dstTop, float dstRight, float dstBottom,
const SkPaint* paint) {
if (quickRejectSetupScissor(dstLeft, dstTop, dstRight, dstBottom)) {
- return DrawGlInfo::kStatusDone;
+ return;
}
mCaches.activeTexture(0);
Texture* texture = getTexture(bitmap);
- if (!texture) return DrawGlInfo::kStatusDone;
+ if (!texture) return;
const AutoTexture autoCleanup(texture);
const float width = texture->width;
@@ -2255,33 +2259,33 @@
resetDrawTextureTexCoords(0.0f, 0.0f, 1.0f, 1.0f);
- return DrawGlInfo::kStatusDrew;
+ mDirty = true;
}
-status_t OpenGLRenderer::drawPatch(const SkBitmap* bitmap, const Res_png_9patch* patch,
+void OpenGLRenderer::drawPatch(const SkBitmap* bitmap, const Res_png_9patch* patch,
float left, float top, float right, float bottom, const SkPaint* paint) {
if (quickRejectSetupScissor(left, top, right, bottom)) {
- return DrawGlInfo::kStatusDone;
+ return;
}
AssetAtlas::Entry* entry = mCaches.assetAtlas.getEntry(bitmap);
const Patch* mesh = mCaches.patchCache.get(entry, bitmap->width(), bitmap->height(),
right - left, bottom - top, patch);
- return drawPatch(bitmap, mesh, entry, left, top, right, bottom, paint);
+ drawPatch(bitmap, mesh, entry, left, top, right, bottom, paint);
}
-status_t OpenGLRenderer::drawPatch(const SkBitmap* bitmap, const Patch* mesh,
+void OpenGLRenderer::drawPatch(const SkBitmap* bitmap, const Patch* mesh,
AssetAtlas::Entry* entry, float left, float top, float right, float bottom,
const SkPaint* paint) {
if (quickRejectSetupScissor(left, top, right, bottom)) {
- return DrawGlInfo::kStatusDone;
+ return;
}
if (CC_LIKELY(mesh && mesh->verticesCount > 0)) {
mCaches.activeTexture(0);
Texture* texture = entry ? entry->texture : mCaches.textureCache.get(bitmap);
- if (!texture) return DrawGlInfo::kStatusDone;
+ if (!texture) return;
const AutoTexture autoCleanup(texture);
texture->setWrap(GL_CLAMP_TO_EDGE, true);
@@ -2323,7 +2327,7 @@
mCaches.patchCache.getMeshBuffer(), kModelViewMode_Translate, !mesh->hasEmptyQuads);
}
- return DrawGlInfo::kStatusDrew;
+ mDirty = true;
}
/**
@@ -2331,11 +2335,11 @@
* will not set the scissor enable or dirty the current layer, if any.
* The caller is responsible for properly dirtying the current layer.
*/
-status_t OpenGLRenderer::drawPatches(const SkBitmap* bitmap, AssetAtlas::Entry* entry,
+void OpenGLRenderer::drawPatches(const SkBitmap* bitmap, AssetAtlas::Entry* entry,
TextureVertex* vertices, uint32_t indexCount, const SkPaint* paint) {
mCaches.activeTexture(0);
Texture* texture = entry ? entry->texture : mCaches.textureCache.get(bitmap);
- if (!texture) return DrawGlInfo::kStatusDone;
+ if (!texture) return;
const AutoTexture autoCleanup(texture);
texture->setWrap(GL_CLAMP_TO_EDGE, true);
@@ -2345,15 +2349,15 @@
texture->blend, &vertices[0].x, &vertices[0].u,
GL_TRIANGLES, indexCount, false, true, 0, kModelViewMode_Translate, false);
- return DrawGlInfo::kStatusDrew;
+ mDirty = true;
}
-status_t OpenGLRenderer::drawVertexBuffer(float translateX, float translateY,
+void OpenGLRenderer::drawVertexBuffer(float translateX, float translateY,
const VertexBuffer& vertexBuffer, const SkPaint* paint, int displayFlags) {
// not missing call to quickReject/dirtyLayer, always done at a higher level
if (!vertexBuffer.getVertexCount()) {
// no vertices to draw
- return DrawGlInfo::kStatusDone;
+ return;
}
Rect bounds(vertexBuffer.getBounds());
@@ -2366,7 +2370,7 @@
setupDraw();
setupDrawNoTexture();
if (isAA) setupDrawVertexAlpha((displayFlags & kVertexBuffer_ShadowInterp));
- setupDrawColor(color, ((color >> 24) & 0xFF) * mSnapshot->alpha);
+ setupDrawColor(color, ((color >> 24) & 0xFF) * writableSnapshot()->alpha);
setupDrawColorFilter(getColorFilter(paint));
setupDrawShader(getShader(paint));
setupDrawBlending(paint, isAA);
@@ -2411,7 +2415,7 @@
glDisableVertexAttribArray(alphaSlot);
}
- return DrawGlInfo::kStatusDrew;
+ mDirty = true;
}
/**
@@ -2423,11 +2427,11 @@
*
* Doesn't yet support joins, caps, or path effects.
*/
-status_t OpenGLRenderer::drawConvexPath(const SkPath& path, const SkPaint* paint) {
+void OpenGLRenderer::drawConvexPath(const SkPath& path, const SkPaint* paint) {
VertexBuffer vertexBuffer;
// TODO: try clipping large paths to viewport
PathTessellator::tessellatePath(path, paint, *currentTransform(), vertexBuffer);
- return drawVertexBuffer(vertexBuffer, paint);
+ drawVertexBuffer(vertexBuffer, paint);
}
/**
@@ -2441,8 +2445,8 @@
* TODO: try using a fixed input buffer for non-capped lines as in text rendering. this may reduce
* memory transfer by removing need for degenerate vertices.
*/
-status_t OpenGLRenderer::drawLines(const float* points, int count, const SkPaint* paint) {
- if (currentSnapshot()->isIgnored() || count < 4) return DrawGlInfo::kStatusDone;
+void OpenGLRenderer::drawLines(const float* points, int count, const SkPaint* paint) {
+ if (mState.currentlyIgnored() || count < 4) return;
count &= ~0x3; // round down to nearest four
@@ -2451,15 +2455,15 @@
const Rect& bounds = buffer.getBounds();
if (quickRejectSetupScissor(bounds.left, bounds.top, bounds.right, bounds.bottom)) {
- return DrawGlInfo::kStatusDone;
+ return;
}
int displayFlags = paint->isAntiAlias() ? 0 : kVertexBuffer_Offset;
- return drawVertexBuffer(buffer, paint, displayFlags);
+ drawVertexBuffer(buffer, paint, displayFlags);
}
-status_t OpenGLRenderer::drawPoints(const float* points, int count, const SkPaint* paint) {
- if (currentSnapshot()->isIgnored() || count < 2) return DrawGlInfo::kStatusDone;
+void OpenGLRenderer::drawPoints(const float* points, int count, const SkPaint* paint) {
+ if (mState.currentlyIgnored() || count < 2) return;
count &= ~0x1; // round down to nearest two
@@ -2468,18 +2472,20 @@
const Rect& bounds = buffer.getBounds();
if (quickRejectSetupScissor(bounds.left, bounds.top, bounds.right, bounds.bottom)) {
- return DrawGlInfo::kStatusDone;
+ return;
}
int displayFlags = paint->isAntiAlias() ? 0 : kVertexBuffer_Offset;
- return drawVertexBuffer(buffer, paint, displayFlags);
+ drawVertexBuffer(buffer, paint, displayFlags);
+
+ mDirty = true;
}
-status_t OpenGLRenderer::drawColor(int color, SkXfermode::Mode mode) {
+void OpenGLRenderer::drawColor(int color, SkXfermode::Mode mode) {
// No need to check against the clip, we fill the clip region
- if (currentSnapshot()->isIgnored()) return DrawGlInfo::kStatusDone;
+ if (mState.currentlyIgnored()) return;
- Rect clip(*currentClipRect());
+ Rect clip(*mState.currentClipRect());
clip.snapToPixelBoundaries();
SkPaint paint;
@@ -2488,12 +2494,12 @@
drawColorRect(clip.left, clip.top, clip.right, clip.bottom, &paint, true);
- return DrawGlInfo::kStatusDrew;
+ mDirty = true;
}
-status_t OpenGLRenderer::drawShape(float left, float top, const PathTexture* texture,
+void OpenGLRenderer::drawShape(float left, float top, const PathTexture* texture,
const SkPaint* paint) {
- if (!texture) return DrawGlInfo::kStatusDone;
+ if (!texture) return;
const AutoTexture autoCleanup(texture);
const float x = left + texture->left - texture->offset;
@@ -2501,79 +2507,79 @@
drawPathTexture(texture, x, y, paint);
- return DrawGlInfo::kStatusDrew;
+ mDirty = true;
}
-status_t OpenGLRenderer::drawRoundRect(float left, float top, float right, float bottom,
+void OpenGLRenderer::drawRoundRect(float left, float top, float right, float bottom,
float rx, float ry, const SkPaint* p) {
- if (currentSnapshot()->isIgnored()
+ if (mState.currentlyIgnored()
|| quickRejectSetupScissor(left, top, right, bottom, p)
|| paintWillNotDraw(*p)) {
- return DrawGlInfo::kStatusDone;
+ return;
}
if (p->getPathEffect() != 0) {
mCaches.activeTexture(0);
const PathTexture* texture = mCaches.pathCache.getRoundRect(
right - left, bottom - top, rx, ry, p);
- return drawShape(left, top, texture, p);
+ drawShape(left, top, texture, p);
+ } else {
+ const VertexBuffer* vertexBuffer = mCaches.tessellationCache.getRoundRect(
+ *currentTransform(), *p, right - left, bottom - top, rx, ry);
+ drawVertexBuffer(left, top, *vertexBuffer, p);
}
-
- const VertexBuffer* vertexBuffer = mCaches.tessellationCache.getRoundRect(
- *currentTransform(), *p, right - left, bottom - top, rx, ry);
- return drawVertexBuffer(left, top, *vertexBuffer, p);
}
-status_t OpenGLRenderer::drawCircle(float x, float y, float radius, const SkPaint* p) {
- if (currentSnapshot()->isIgnored()
+void OpenGLRenderer::drawCircle(float x, float y, float radius, const SkPaint* p) {
+ if (mState.currentlyIgnored()
|| quickRejectSetupScissor(x - radius, y - radius, x + radius, y + radius, p)
|| paintWillNotDraw(*p)) {
- return DrawGlInfo::kStatusDone;
+ return;
}
if (p->getPathEffect() != 0) {
mCaches.activeTexture(0);
const PathTexture* texture = mCaches.pathCache.getCircle(radius, p);
- return drawShape(x - radius, y - radius, texture, p);
- }
-
- SkPath path;
- if (p->getStyle() == SkPaint::kStrokeAndFill_Style) {
- path.addCircle(x, y, radius + p->getStrokeWidth() / 2);
+ drawShape(x - radius, y - radius, texture, p);
} else {
- path.addCircle(x, y, radius);
+ SkPath path;
+ if (p->getStyle() == SkPaint::kStrokeAndFill_Style) {
+ path.addCircle(x, y, radius + p->getStrokeWidth() / 2);
+ } else {
+ path.addCircle(x, y, radius);
+ }
+ drawConvexPath(path, p);
}
- return drawConvexPath(path, p);
}
-status_t OpenGLRenderer::drawOval(float left, float top, float right, float bottom,
+void OpenGLRenderer::drawOval(float left, float top, float right, float bottom,
const SkPaint* p) {
- if (currentSnapshot()->isIgnored()
+ if (mState.currentlyIgnored()
|| quickRejectSetupScissor(left, top, right, bottom, p)
|| paintWillNotDraw(*p)) {
- return DrawGlInfo::kStatusDone;
+ return;
}
if (p->getPathEffect() != 0) {
mCaches.activeTexture(0);
const PathTexture* texture = mCaches.pathCache.getOval(right - left, bottom - top, p);
- return drawShape(left, top, texture, p);
+ drawShape(left, top, texture, p);
+ } else {
+ SkPath path;
+ SkRect rect = SkRect::MakeLTRB(left, top, right, bottom);
+ if (p->getStyle() == SkPaint::kStrokeAndFill_Style) {
+ rect.outset(p->getStrokeWidth() / 2, p->getStrokeWidth() / 2);
+ }
+ path.addOval(rect);
+ drawConvexPath(path, p);
}
-
- SkPath path;
- SkRect rect = SkRect::MakeLTRB(left, top, right, bottom);
- if (p->getStyle() == SkPaint::kStrokeAndFill_Style) {
- rect.outset(p->getStrokeWidth() / 2, p->getStrokeWidth() / 2);
- }
- path.addOval(rect);
- return drawConvexPath(path, p);
}
-status_t OpenGLRenderer::drawArc(float left, float top, float right, float bottom,
+void OpenGLRenderer::drawArc(float left, float top, float right, float bottom,
float startAngle, float sweepAngle, bool useCenter, const SkPaint* p) {
- if (currentSnapshot()->isIgnored()
+ if (mState.currentlyIgnored()
|| quickRejectSetupScissor(left, top, right, bottom, p)
|| paintWillNotDraw(*p)) {
- return DrawGlInfo::kStatusDone;
+ return;
}
// TODO: support fills (accounting for concavity if useCenter && sweepAngle > 180)
@@ -2581,9 +2587,9 @@
mCaches.activeTexture(0);
const PathTexture* texture = mCaches.pathCache.getArc(right - left, bottom - top,
startAngle, sweepAngle, useCenter, p);
- return drawShape(left, top, texture, p);
+ drawShape(left, top, texture, p);
+ return;
}
-
SkRect rect = SkRect::MakeLTRB(left, top, right, bottom);
if (p->getStyle() == SkPaint::kStrokeAndFill_Style) {
rect.outset(p->getStrokeWidth() / 2, p->getStrokeWidth() / 2);
@@ -2597,18 +2603,18 @@
if (useCenter) {
path.close();
}
- return drawConvexPath(path, p);
+ drawConvexPath(path, p);
}
// See SkPaintDefaults.h
#define SkPaintDefaults_MiterLimit SkIntToScalar(4)
-status_t OpenGLRenderer::drawRect(float left, float top, float right, float bottom,
+void OpenGLRenderer::drawRect(float left, float top, float right, float bottom,
const SkPaint* p) {
- if (currentSnapshot()->isIgnored()
+ if (mState.currentlyIgnored()
|| quickRejectSetupScissor(left, top, right, bottom, p)
|| paintWillNotDraw(*p)) {
- return DrawGlInfo::kStatusDone;
+ return;
}
if (p->getStyle() != SkPaint::kFill_Style) {
@@ -2618,25 +2624,26 @@
mCaches.activeTexture(0);
const PathTexture* texture =
mCaches.pathCache.getRect(right - left, bottom - top, p);
- return drawShape(left, top, texture, p);
+ drawShape(left, top, texture, p);
+ } else {
+ SkPath path;
+ SkRect rect = SkRect::MakeLTRB(left, top, right, bottom);
+ if (p->getStyle() == SkPaint::kStrokeAndFill_Style) {
+ rect.outset(p->getStrokeWidth() / 2, p->getStrokeWidth() / 2);
+ }
+ path.addRect(rect);
+ drawConvexPath(path, p);
}
-
- SkPath path;
- SkRect rect = SkRect::MakeLTRB(left, top, right, bottom);
- if (p->getStyle() == SkPaint::kStrokeAndFill_Style) {
- rect.outset(p->getStrokeWidth() / 2, p->getStrokeWidth() / 2);
- }
- path.addRect(rect);
- return drawConvexPath(path, p);
- }
-
- if (p->isAntiAlias() && !currentTransform()->isSimple()) {
- SkPath path;
- path.addRect(left, top, right, bottom);
- return drawConvexPath(path, p);
} else {
- drawColorRect(left, top, right, bottom, p);
- return DrawGlInfo::kStatusDrew;
+ if (p->isAntiAlias() && !currentTransform()->isSimple()) {
+ SkPath path;
+ path.addRect(left, top, right, bottom);
+ drawConvexPath(path, p);
+ } else {
+ drawColorRect(left, top, right, bottom, p);
+
+ mDirty = true;
+ }
}
}
@@ -2663,7 +2670,7 @@
const float sx = x - shadow->left + textShadow.dx;
const float sy = y - shadow->top + textShadow.dy;
- const int shadowAlpha = ((textShadow.color >> 24) & 0xFF) * mSnapshot->alpha;
+ const int shadowAlpha = ((textShadow.color >> 24) & 0xFF) * writableSnapshot()->alpha;
if (getShader(paint)) {
textShadow.color = SK_ColorWHITE;
}
@@ -2687,19 +2694,19 @@
}
bool OpenGLRenderer::canSkipText(const SkPaint* paint) const {
- float alpha = (hasTextShadow(paint) ? 1.0f : paint->getAlpha()) * mSnapshot->alpha;
+ float alpha = (hasTextShadow(paint) ? 1.0f : paint->getAlpha()) * currentSnapshot()->alpha;
return alpha == 0.0f && getXfermode(paint->getXfermode()) == SkXfermode::kSrcOver_Mode;
}
-status_t OpenGLRenderer::drawPosText(const char* text, int bytesCount, int count,
+void OpenGLRenderer::drawPosText(const char* text, int bytesCount, int count,
const float* positions, const SkPaint* paint) {
- if (text == NULL || count == 0 || currentSnapshot()->isIgnored() || canSkipText(paint)) {
- return DrawGlInfo::kStatusDone;
+ if (text == NULL || count == 0 || mState.currentlyIgnored() || canSkipText(paint)) {
+ return;
}
// NOTE: Skia does not support perspective transform on drawPosText yet
if (!currentTransform()->isSimple()) {
- return DrawGlInfo::kStatusDone;
+ return;
}
mCaches.enableScissor();
@@ -2731,7 +2738,7 @@
}
fontRenderer.setTextureFiltering(linearFilter);
- const Rect* clip = pureTranslate ? mSnapshot->clipRect : &mSnapshot->getLocalClip();
+ const Rect* clip = pureTranslate ? writableSnapshot()->clipRect : &writableSnapshot()->getLocalClip();
Rect bounds(FLT_MAX / 2.0f, FLT_MAX / 2.0f, FLT_MIN / 2.0f, FLT_MIN / 2.0f);
const bool hasActiveLayer = hasLayer();
@@ -2747,7 +2754,7 @@
}
}
- return DrawGlInfo::kStatusDrew;
+ mDirty = true;
}
bool OpenGLRenderer::findBestFontTransform(const mat4& transform, SkMatrix* outMatrix) const {
@@ -2771,16 +2778,79 @@
return true;
}
-status_t OpenGLRenderer::drawText(const char* text, int bytesCount, int count, float x, float y,
+int OpenGLRenderer::getSaveCount() const {
+ return mState.getSaveCount();
+}
+
+int OpenGLRenderer::save(int flags) {
+ return mState.save(flags);
+}
+
+void OpenGLRenderer::restore() {
+ return mState.restore();
+}
+
+void OpenGLRenderer::restoreToCount(int saveCount) {
+ return mState.restoreToCount(saveCount);
+}
+
+void OpenGLRenderer::translate(float dx, float dy, float dz) {
+ return mState.translate(dx, dy, dz);
+}
+
+void OpenGLRenderer::rotate(float degrees) {
+ return mState.rotate(degrees);
+}
+
+void OpenGLRenderer::scale(float sx, float sy) {
+ return mState.scale(sx, sy);
+}
+
+void OpenGLRenderer::skew(float sx, float sy) {
+ return mState.skew(sx, sy);
+}
+
+void OpenGLRenderer::setMatrix(const Matrix4& matrix) {
+ mState.setMatrix(matrix);
+}
+
+void OpenGLRenderer::concatMatrix(const Matrix4& matrix) {
+ mState.concatMatrix(matrix);
+}
+
+bool OpenGLRenderer::clipRect(float left, float top, float right, float bottom, SkRegion::Op op) {
+ return mState.clipRect(left, top, right, bottom, op);
+}
+
+bool OpenGLRenderer::clipPath(const SkPath* path, SkRegion::Op op) {
+ return mState.clipPath(path, op);
+}
+
+bool OpenGLRenderer::clipRegion(const SkRegion* region, SkRegion::Op op) {
+ return mState.clipRegion(region, op);
+}
+
+void OpenGLRenderer::setClippingOutline(LinearAllocator& allocator, const Outline* outline) {
+ mState.setClippingOutline(allocator, outline);
+}
+
+void OpenGLRenderer::setClippingRoundRect(LinearAllocator& allocator,
+ const Rect& rect, float radius, bool highPriority) {
+ mState.setClippingRoundRect(allocator, rect, radius, highPriority);
+}
+
+
+
+void OpenGLRenderer::drawText(const char* text, int bytesCount, int count, float x, float y,
const float* positions, const SkPaint* paint, float totalAdvance, const Rect& bounds,
DrawOpMode drawOpMode) {
if (drawOpMode == kDrawOpMode_Immediate) {
// The checks for corner-case ignorable text and quick rejection is only done for immediate
// drawing as ops from DeferredDisplayList are already filtered for these
- if (text == NULL || count == 0 || currentSnapshot()->isIgnored() || canSkipText(paint) ||
+ if (text == NULL || count == 0 || mState.currentlyIgnored() || canSkipText(paint) ||
quickRejectSetupScissor(bounds)) {
- return DrawGlInfo::kStatusDone;
+ return;
}
}
@@ -2828,7 +2898,7 @@
fontRenderer.setTextureFiltering(linearFilter);
// TODO: Implement better clipping for scaled/rotated text
- const Rect* clip = !pureTranslate ? NULL : currentClipRect();
+ const Rect* clip = !pureTranslate ? NULL : mState.currentClipRect();
Rect layerBounds(FLT_MAX / 2.0f, FLT_MAX / 2.0f, FLT_MIN / 2.0f, FLT_MIN / 2.0f);
bool status;
@@ -2855,13 +2925,13 @@
drawTextDecorations(totalAdvance, oldX, oldY, paint);
- return DrawGlInfo::kStatusDrew;
+ mDirty = true;
}
-status_t OpenGLRenderer::drawTextOnPath(const char* text, int bytesCount, int count,
+void OpenGLRenderer::drawTextOnPath(const char* text, int bytesCount, int count,
const SkPath* path, float hOffset, float vOffset, const SkPaint* paint) {
- if (text == NULL || count == 0 || currentSnapshot()->isIgnored() || canSkipText(paint)) {
- return DrawGlInfo::kStatusDone;
+ if (text == NULL || count == 0 || mState.currentlyIgnored() || canSkipText(paint)) {
+ return;
}
// TODO: avoid scissor by calculating maximum bounds using path bounds + font metrics
@@ -2876,7 +2946,7 @@
getAlphaAndMode(paint, &alpha, &mode);
TextSetupFunctor functor(this, 0.0f, 0.0f, false, alpha, mode, paint);
- const Rect* clip = &mSnapshot->getLocalClip();
+ const Rect* clip = &writableSnapshot()->getLocalClip();
Rect bounds(FLT_MAX / 2.0f, FLT_MAX / 2.0f, FLT_MIN / 2.0f, FLT_MIN / 2.0f);
const bool hasActiveLayer = hasLayer();
@@ -2889,29 +2959,28 @@
}
}
- return DrawGlInfo::kStatusDrew;
+ mDirty = true;
}
-status_t OpenGLRenderer::drawPath(const SkPath* path, const SkPaint* paint) {
- if (currentSnapshot()->isIgnored()) return DrawGlInfo::kStatusDone;
+void OpenGLRenderer::drawPath(const SkPath* path, const SkPaint* paint) {
+ if (mState.currentlyIgnored()) return;
mCaches.activeTexture(0);
const PathTexture* texture = mCaches.pathCache.get(path, paint);
- if (!texture) return DrawGlInfo::kStatusDone;
+ if (!texture) return;
const AutoTexture autoCleanup(texture);
const float x = texture->left - texture->offset;
const float y = texture->top - texture->offset;
drawPathTexture(texture, x, y, paint);
-
- return DrawGlInfo::kStatusDrew;
+ mDirty = true;
}
-status_t OpenGLRenderer::drawLayer(Layer* layer, float x, float y) {
+void OpenGLRenderer::drawLayer(Layer* layer, float x, float y) {
if (!layer) {
- return DrawGlInfo::kStatusDone;
+ return;
}
mat4* transform = NULL;
@@ -2924,14 +2993,14 @@
}
bool clipRequired = false;
- const bool rejected = calculateQuickRejectForScissor(x, y,
+ const bool rejected = mState.calculateQuickRejectForScissor(x, y,
x + layer->layer.getWidth(), y + layer->layer.getHeight(), &clipRequired, NULL, false);
if (rejected) {
if (transform && !transform->isIdentity()) {
restore();
}
- return DrawGlInfo::kStatusDone;
+ return;
}
EVENT_LOGD("drawLayer," RECT_STRING ", clipRequired %d", x, y,
@@ -3006,53 +3075,16 @@
restore();
}
- return DrawGlInfo::kStatusDrew;
+ mDirty = true;
}
///////////////////////////////////////////////////////////////////////////////
// Draw filters
///////////////////////////////////////////////////////////////////////////////
-
-void OpenGLRenderer::resetPaintFilter() {
- // when clearing the PaintFilter, the masks should also be cleared for simple DrawModifier
- // comparison, see MergingDrawBatch::canMergeWith
- mDrawModifiers.mHasDrawFilter = false;
- mDrawModifiers.mPaintFilterClearBits = 0;
- mDrawModifiers.mPaintFilterSetBits = 0;
-}
-
-void OpenGLRenderer::setupPaintFilter(int clearBits, int setBits) {
- // TODO: don't bother with boolean, it's redundant with clear/set bits
- mDrawModifiers.mHasDrawFilter = true;
- mDrawModifiers.mPaintFilterClearBits = clearBits & SkPaint::kAllFlags;
- mDrawModifiers.mPaintFilterSetBits = setBits & SkPaint::kAllFlags;
-}
-
-const SkPaint* OpenGLRenderer::filterPaint(const SkPaint* paint) {
- // TODO: use CompatFlagsDrawFilter here, and combine logic with android/graphics/DrawFilter.cpp
- // to avoid clobbering 0x02 paint flag
-
- // Equivalent to the Java Paint's FILTER_BITMAP_FLAG.
- static const uint32_t sFilterBitmapFlag = 0x02;
-
- if (CC_LIKELY(!mDrawModifiers.mHasDrawFilter || !paint)) {
- return paint;
- }
-
- const uint32_t clearBits = mDrawModifiers.mPaintFilterClearBits;
- const uint32_t setBits = mDrawModifiers.mPaintFilterSetBits;
-
- const uint32_t flags = (paint->getFlags() & ~clearBits) | setBits;
- mFilteredPaint = *paint;
- mFilteredPaint.setFlags(flags);
-
- // check if paint filter trying to override bitmap filter
- if ((clearBits | setBits) & sFilterBitmapFlag) {
- mFilteredPaint.setFilterLevel(flags & sFilterBitmapFlag
- ? SkPaint::kLow_FilterLevel : SkPaint::kNone_FilterLevel);
- }
-
- return &mFilteredPaint;
+void OpenGLRenderer::setDrawFilter(SkDrawFilter* filter) {
+ // We should never get here since we apply the draw filter when stashing
+ // the paints in the DisplayList.
+ LOG_ALWAYS_FATAL("OpenGLRenderer does not directly support DrawFilters");
}
///////////////////////////////////////////////////////////////////////////////
@@ -3145,12 +3177,12 @@
}
}
-status_t OpenGLRenderer::drawRects(const float* rects, int count, const SkPaint* paint) {
- if (currentSnapshot()->isIgnored()) {
- return DrawGlInfo::kStatusDone;
+void OpenGLRenderer::drawRects(const float* rects, int count, const SkPaint* paint) {
+ if (mState.currentlyIgnored()) {
+ return;
}
- return drawColorRects(rects, count, paint, false, true, true);
+ drawColorRects(rects, count, paint, false, true, true);
}
static void mapPointFakeZ(Vector3& point, const mat4& transformXY, const mat4& transformZ) {
@@ -3161,9 +3193,9 @@
transformXY.mapPoint(point.x, point.y);
}
-status_t OpenGLRenderer::drawShadow(float casterAlpha,
+void OpenGLRenderer::drawShadow(float casterAlpha,
const VertexBuffer* ambientShadowVertexBuffer, const VertexBuffer* spotShadowVertexBuffer) {
- if (currentSnapshot()->isIgnored()) return DrawGlInfo::kStatusDone;
+ if (mState.currentlyIgnored()) return;
// TODO: use quickRejectWithScissor. For now, always force enable scissor.
mCaches.enableScissor();
@@ -3190,13 +3222,13 @@
drawVertexBuffer(*spotShadowVertexBuffer, &paint, kVertexBuffer_ShadowInterp);
}
- return DrawGlInfo::kStatusDrew;
+ mDirty=true;
}
-status_t OpenGLRenderer::drawColorRects(const float* rects, int count, const SkPaint* paint,
+void OpenGLRenderer::drawColorRects(const float* rects, int count, const SkPaint* paint,
bool ignoreTransform, bool dirty, bool clip) {
if (count == 0) {
- return DrawGlInfo::kStatusDone;
+ return;
}
int color = paint->getColor();
@@ -3231,7 +3263,7 @@
}
if (clip && quickRejectSetupScissor(left, top, right, bottom)) {
- return DrawGlInfo::kStatusDone;
+ return;
}
setupDraw();
@@ -3254,7 +3286,7 @@
issueIndexedQuadDraw(&mesh[0], count / 4);
- return DrawGlInfo::kStatusDrew;
+ mDirty = true;
}
void OpenGLRenderer::drawColorRect(float left, float top, float right, float bottom,
@@ -3405,7 +3437,7 @@
void OpenGLRenderer::chooseBlending(bool blend, SkXfermode::Mode mode,
ProgramDescription& description, bool swapSrcDst) {
- if (mSnapshot->roundRectClipState != NULL /*&& !mSkipOutlineClip*/) {
+ if (writableSnapshot()->roundRectClipState != NULL /*&& !mSkipOutlineClip*/) {
blend = true;
mDescription.hasRoundRectClip = true;
}
diff --git a/libs/hwui/OpenGLRenderer.h b/libs/hwui/OpenGLRenderer.h
index e1c3d10..fde9e0f 100755
--- a/libs/hwui/OpenGLRenderer.h
+++ b/libs/hwui/OpenGLRenderer.h
@@ -38,6 +38,7 @@
#include <androidfw/ResourceTypes.h>
+#include "CanvasState.h"
#include "Debug.h"
#include "Extensions.h"
#include "Matrix.h"
@@ -45,11 +46,9 @@
#include "Rect.h"
#include "Renderer.h"
#include "Snapshot.h"
-#include "StatefulBaseRenderer.h"
#include "UvMapper.h"
#include "Vertex.h"
#include "Caches.h"
-#include "CanvasProperty.h"
class SkShader;
@@ -72,11 +71,6 @@
}
float mOverrideLayerAlpha;
-
- // Draw filters
- bool mHasDrawFilter;
- int mPaintFilterClearBits;
- int mPaintFilterSetBits;
};
enum StateDeferFlags {
@@ -123,7 +117,7 @@
/**
* OpenGL Renderer implementation.
*/
-class OpenGLRenderer : public StatefulBaseRenderer {
+class OpenGLRenderer : public Renderer, public CanvasStateClient {
public:
OpenGLRenderer(RenderState& renderState);
virtual ~OpenGLRenderer();
@@ -132,11 +126,13 @@
void initLight(const Vector3& lightCenter, float lightRadius,
uint8_t ambientShadowAlpha, uint8_t spotShadowAlpha);
- virtual void onViewportInitialized();
- virtual status_t prepareDirty(float left, float top, float right, float bottom, bool opaque);
- virtual void finish();
+ virtual void prepareDirty(float left, float top, float right, float bottom, bool opaque);
+ virtual void prepare(bool opaque) {
+ prepareDirty(0.0f, 0.0f, mState.getWidth(), mState.getHeight(), opaque);
+ }
+ virtual bool finish();
- virtual status_t callDrawGLFunction(Functor* functor, Rect& dirty);
+ virtual void callDrawGLFunction(Functor* functor, Rect& dirty);
void pushLayerUpdate(Layer* layer);
void cancelLayerUpdate(Layer* layer);
@@ -156,56 +152,53 @@
int saveLayerDeferred(float left, float top, float right, float bottom,
const SkPaint* paint, int flags);
- virtual status_t drawRenderNode(RenderNode* displayList, Rect& dirty, int32_t replayFlags = 1);
- virtual status_t drawLayer(Layer* layer, float x, float y);
- virtual status_t drawBitmap(const SkBitmap* bitmap, const SkPaint* paint);
- status_t drawBitmaps(const SkBitmap* bitmap, AssetAtlas::Entry* entry, int bitmapCount,
+ virtual void drawRenderNode(RenderNode* displayList, Rect& dirty, int32_t replayFlags = 1);
+ virtual void drawLayer(Layer* layer, float x, float y);
+ virtual void drawBitmap(const SkBitmap* bitmap, const SkPaint* paint);
+ void drawBitmaps(const SkBitmap* bitmap, AssetAtlas::Entry* entry, int bitmapCount,
TextureVertex* vertices, bool pureTranslate, const Rect& bounds, const SkPaint* paint);
- virtual status_t drawBitmap(const SkBitmap* bitmap, float srcLeft, float srcTop,
+ virtual void drawBitmap(const SkBitmap* bitmap, float srcLeft, float srcTop,
float srcRight, float srcBottom, float dstLeft, float dstTop,
float dstRight, float dstBottom, const SkPaint* paint);
- virtual status_t drawBitmapData(const SkBitmap* bitmap, const SkPaint* paint);
- virtual status_t drawBitmapMesh(const SkBitmap* bitmap, int meshWidth, int meshHeight,
+ virtual void drawBitmapData(const SkBitmap* bitmap, const SkPaint* paint);
+ virtual void drawBitmapMesh(const SkBitmap* bitmap, int meshWidth, int meshHeight,
const float* vertices, const int* colors, const SkPaint* paint);
- status_t drawPatches(const SkBitmap* bitmap, AssetAtlas::Entry* entry,
+ void drawPatches(const SkBitmap* bitmap, AssetAtlas::Entry* entry,
TextureVertex* vertices, uint32_t indexCount, const SkPaint* paint);
- virtual status_t drawPatch(const SkBitmap* bitmap, const Res_png_9patch* patch,
+ virtual void drawPatch(const SkBitmap* bitmap, const Res_png_9patch* patch,
float left, float top, float right, float bottom, const SkPaint* paint);
- status_t drawPatch(const SkBitmap* bitmap, const Patch* mesh, AssetAtlas::Entry* entry,
+ void drawPatch(const SkBitmap* bitmap, const Patch* mesh, AssetAtlas::Entry* entry,
float left, float top, float right, float bottom, const SkPaint* paint);
- virtual status_t drawColor(int color, SkXfermode::Mode mode);
- virtual status_t drawRect(float left, float top, float right, float bottom,
+ virtual void drawColor(int color, SkXfermode::Mode mode);
+ virtual void drawRect(float left, float top, float right, float bottom,
const SkPaint* paint);
- virtual status_t drawRoundRect(float left, float top, float right, float bottom,
+ virtual void drawRoundRect(float left, float top, float right, float bottom,
float rx, float ry, const SkPaint* paint);
- virtual status_t drawCircle(float x, float y, float radius, const SkPaint* paint);
- virtual status_t drawOval(float left, float top, float right, float bottom,
+ virtual void drawCircle(float x, float y, float radius, const SkPaint* paint);
+ virtual void drawOval(float left, float top, float right, float bottom,
const SkPaint* paint);
- virtual status_t drawArc(float left, float top, float right, float bottom,
+ virtual void drawArc(float left, float top, float right, float bottom,
float startAngle, float sweepAngle, bool useCenter, const SkPaint* paint);
- virtual status_t drawPath(const SkPath* path, const SkPaint* paint);
- virtual status_t drawLines(const float* points, int count, const SkPaint* paint);
- virtual status_t drawPoints(const float* points, int count, const SkPaint* paint);
- virtual status_t drawTextOnPath(const char* text, int bytesCount, int count, const SkPath* path,
+ virtual void drawPath(const SkPath* path, const SkPaint* paint);
+ virtual void drawLines(const float* points, int count, const SkPaint* paint);
+ virtual void drawPoints(const float* points, int count, const SkPaint* paint);
+ virtual void drawTextOnPath(const char* text, int bytesCount, int count, const SkPath* path,
float hOffset, float vOffset, const SkPaint* paint);
- virtual status_t drawPosText(const char* text, int bytesCount, int count,
+ virtual void drawPosText(const char* text, int bytesCount, int count,
const float* positions, const SkPaint* paint);
- virtual status_t drawText(const char* text, int bytesCount, int count, float x, float y,
+ virtual void drawText(const char* text, int bytesCount, int count, float x, float y,
const float* positions, const SkPaint* paint, float totalAdvance, const Rect& bounds,
DrawOpMode drawOpMode = kDrawOpMode_Immediate);
- virtual status_t drawRects(const float* rects, int count, const SkPaint* paint);
+ virtual void drawRects(const float* rects, int count, const SkPaint* paint);
- status_t drawShadow(float casterAlpha,
+ void drawShadow(float casterAlpha,
const VertexBuffer* ambientShadowVertexBuffer, const VertexBuffer* spotShadowVertexBuffer);
- virtual void resetPaintFilter();
- virtual void setupPaintFilter(int clearBits, int setBits);
+ virtual void setDrawFilter(SkDrawFilter* filter);
// If this value is set to < 1.0, it overrides alpha set on layer (see drawBitmap, drawLayer)
void setOverrideLayerAlpha(float alpha) { mDrawModifiers.mOverrideLayerAlpha = alpha; }
- const SkPaint* filterPaint(const SkPaint* paint);
-
/**
* Store the current display state (most importantly, the current clip and transform), and
* additionally map the state's bounds from local to window coordinates.
@@ -228,20 +221,16 @@
}
// simple rect clip
- bool isCurrentClipSimple() {
- return mSnapshot->clipRegion->isEmpty();
- }
+ bool isCurrentClipSimple() { return mState.isCurrentClipSimple(); }
- int getViewportWidth() { return currentSnapshot()->getViewportWidth(); }
- int getViewportHeight() { return currentSnapshot()->getViewportHeight(); }
+ int getViewportWidth() { return mState.getViewportWidth(); }
+ int getViewportHeight() { return mState.getViewportHeight(); }
/**
* Scales the alpha on the current snapshot. This alpha value will be modulated
* with other alpha values when drawing primitives.
*/
- void scaleAlpha(float alpha) {
- mSnapshot->alpha *= alpha;
- }
+ void scaleAlpha(float alpha) { mState.scaleAlpha(alpha); }
/**
* Inserts a named event marker in the stream of GL commands.
@@ -334,14 +323,67 @@
drawColorRect(left, top, right, bottom, color, SkXfermode::kSrcOver_Mode, true);
if (stencilWasEnabled) mCaches.stencil.enableTest();
+ mDirty = true;
}
#endif
- const Vector3& getLightCenter() const { return currentSnapshot()->getRelativeLightCenter(); }
+ const Vector3& getLightCenter() const { return mState.currentLightCenter(); }
float getLightRadius() const { return mLightRadius; }
uint8_t getAmbientShadowAlpha() const { return mAmbientShadowAlpha; }
uint8_t getSpotShadowAlpha() const { return mSpotShadowAlpha; }
+ ///////////////////////////////////////////////////////////////////
+ /// State manipulation
+
+ virtual void setViewport(int width, int height) { mState.setViewport(width, height); }
+
+ virtual int getSaveCount() const;
+ virtual int save(int flags);
+ virtual void restore();
+ virtual void restoreToCount(int saveCount);
+
+ virtual void getMatrix(SkMatrix* outMatrix) const { mState.getMatrix(outMatrix); }
+ virtual void setMatrix(const SkMatrix& matrix) { mState.setMatrix(matrix); }
+ virtual void concatMatrix(const SkMatrix& matrix) { mState.concatMatrix(matrix); }
+
+ virtual void translate(float dx, float dy, float dz = 0.0f);
+ virtual void rotate(float degrees);
+ virtual void scale(float sx, float sy);
+ virtual void skew(float sx, float sy);
+
+ void setMatrix(const Matrix4& matrix); // internal only convenience method
+ void concatMatrix(const Matrix4& matrix); // internal only convenience method
+
+ virtual const Rect& getLocalClipBounds() const { return mState.getLocalClipBounds(); }
+ const Rect& getRenderTargetClipBounds() const { return mState.getRenderTargetClipBounds(); }
+ virtual bool quickRejectConservative(float left, float top, float right, float bottom) const {
+ return mState.quickRejectConservative(left, top, right, bottom);
+ }
+
+ virtual bool clipRect(float left, float top, float right, float bottom, SkRegion::Op op);
+ virtual bool clipPath(const SkPath* path, SkRegion::Op op);
+ virtual bool clipRegion(const SkRegion* region, SkRegion::Op op);
+
+ /**
+ * Does not support different clipping Ops (that is, every call to setClippingOutline is
+ * effectively using SkRegion::kReplaceOp)
+ *
+ * The clipping outline is independent from the regular clip.
+ */
+ void setClippingOutline(LinearAllocator& allocator, const Outline* outline);
+ void setClippingRoundRect(LinearAllocator& allocator,
+ const Rect& rect, float radius, bool highPriority = true);
+
+ inline bool hasRectToRectTransform() const { return mState.hasRectToRectTransform(); }
+ inline const mat4* currentTransform() const { return mState.currentTransform(); }
+
+ ///////////////////////////////////////////////////////////////////
+ /// CanvasStateClient interface
+
+ virtual void onViewportInitialized();
+ virtual void onSnapshotRestored(const Snapshot& removed, const Snapshot& restored);
+ virtual GLuint onGetTargetFbo() const { return 0; }
+
protected:
/**
* Perform the setup specific to a frame. This method does not
@@ -353,12 +395,12 @@
* Indicates the start of rendering. This method will setup the
* initial OpenGL state (viewport, clearing the buffer, etc.)
*/
- status_t startFrame();
+ void startFrame();
/**
* Clears the underlying surface if needed.
*/
- virtual status_t clear(float left, float top, float right, float bottom, bool opaque);
+ virtual void clear(float left, float top, float right, float bottom, bool opaque);
/**
* Call this method after updating a layer during a drawing pass.
@@ -405,22 +447,16 @@
* Returns the region of the current layer.
*/
virtual Region* getRegion() const {
- return mSnapshot->region;
+ return mState.currentRegion();
}
/**
* Indicates whether rendering is currently targeted at a layer.
*/
virtual bool hasLayer() const {
- return (mSnapshot->flags & Snapshot::kFlagFboTarget) && mSnapshot->region;
+ return (mState.currentFlags() & Snapshot::kFlagFboTarget) && mState.currentRegion();
}
- /**
- * Returns the name of the FBO this renderer is rendering into.
- */
- virtual GLuint getTargetFbo() const {
- return 0;
- }
/**
* Renders the specified layer as a textured quad.
@@ -473,6 +509,8 @@
inline RenderState& renderState() { return mRenderState; }
+ CanvasState mState;
+
private:
/**
* Discards the content of the framebuffer if supported by the driver.
@@ -508,8 +546,6 @@
*/
void endTiling();
- void onSnapshotRestored(const Snapshot& removed, const Snapshot& restored);
-
/**
* Sets the clipping rectangle using glScissor. The clip is defined by
* the current snapshot's clipRect member.
@@ -623,7 +659,7 @@
* @param dirty True if calling this method should dirty the current layer
* @param clip True if the rects should be clipped, false otherwise
*/
- status_t drawColorRects(const float* rects, int count, const SkPaint* paint,
+ void drawColorRects(const float* rects, int count, const SkPaint* paint,
bool ignoreTransform = false, bool dirty = true, bool clip = true);
/**
@@ -637,7 +673,7 @@
* @param texture The texture reprsenting the shape
* @param paint The paint to draw the shape with
*/
- status_t drawShape(float left, float top, const PathTexture* texture, const SkPaint* paint);
+ void drawShape(float left, float top, const PathTexture* texture, const SkPaint* paint);
/**
* Draws the specified texture as an alpha bitmap. Alpha bitmaps obey
@@ -657,15 +693,15 @@
* @param paint The paint to render with
* @param flags flags with which to draw
*/
- status_t drawVertexBuffer(float translateX, float translateY, const VertexBuffer& vertexBuffer,
+ void drawVertexBuffer(float translateX, float translateY, const VertexBuffer& vertexBuffer,
const SkPaint* paint, int flags = 0);
/**
* Convenience for translating method
*/
- status_t drawVertexBuffer(const VertexBuffer& vertexBuffer,
+ void drawVertexBuffer(const VertexBuffer& vertexBuffer,
const SkPaint* paint, int flags = 0) {
- return drawVertexBuffer(0.0f, 0.0f, vertexBuffer, paint, flags);
+ drawVertexBuffer(0.0f, 0.0f, vertexBuffer, paint, flags);
}
/**
@@ -674,7 +710,7 @@
* @param path The hull of the path to draw
* @param paint The paint to render with
*/
- status_t drawConvexPath(const SkPath& path, const SkPaint* paint);
+ void drawConvexPath(const SkPath& path, const SkPaint* paint);
/**
* Draws a textured rectangle with the specified texture. The specified coordinates
@@ -925,9 +961,7 @@
/**
* Should be invoked every time the glScissor is modified.
*/
- inline void dirtyClip() {
- mDirtyClip = true;
- }
+ inline void dirtyClip() { mState.setDirtyClip(true); }
inline const UvMapper& getMapper(const Texture* texture) {
return texture && texture->uvMapper ? *texture->uvMapper : mUvMapper;
@@ -940,6 +974,10 @@
*/
Texture* getTexture(const SkBitmap* bitmap);
+ bool reportAndClearDirty() { bool ret = mDirty; mDirty = false; return ret; }
+ inline Snapshot* writableSnapshot() { return mState.writableSnapshot(); }
+ inline const Snapshot* currentSnapshot() const { return mState.currentSnapshot(); }
+
/**
* Model-view matrix used to position/size objects
*
@@ -1008,6 +1046,10 @@
bool mSkipOutlineClip;
+ // True if anything has been drawn since the last call to
+ // reportAndClearDirty()
+ bool mDirty;
+
// Lighting + shadows
Vector3 mLightCenter;
float mLightRadius;
diff --git a/libs/hwui/Patch.h b/libs/hwui/Patch.h
index 1ba045d..d5bbfa6 100644
--- a/libs/hwui/Patch.h
+++ b/libs/hwui/Patch.h
@@ -27,11 +27,12 @@
#include "Rect.h"
#include "UvMapper.h"
-#include "Vertex.h"
namespace android {
namespace uirenderer {
+class TextureVertex;
+
///////////////////////////////////////////////////////////////////////////////
// 9-patch structures
///////////////////////////////////////////////////////////////////////////////
diff --git a/libs/hwui/PatchCache.cpp b/libs/hwui/PatchCache.cpp
index 2f2debc..1920fcf 100644
--- a/libs/hwui/PatchCache.cpp
+++ b/libs/hwui/PatchCache.cpp
@@ -20,6 +20,7 @@
#include <utils/Log.h>
#include "Caches.h"
+#include "Patch.h"
#include "PatchCache.h"
#include "Properties.h"
diff --git a/libs/hwui/PatchCache.h b/libs/hwui/PatchCache.h
index 9f2c9a5..1e40997 100644
--- a/libs/hwui/PatchCache.h
+++ b/libs/hwui/PatchCache.h
@@ -25,12 +25,13 @@
#include "AssetAtlas.h"
#include "Debug.h"
-#include "Patch.h"
#include "utils/Pair.h"
namespace android {
namespace uirenderer {
+class Patch;
+
///////////////////////////////////////////////////////////////////////////////
// Defines
///////////////////////////////////////////////////////////////////////////////
diff --git a/libs/hwui/PathCache.h b/libs/hwui/PathCache.h
index bc34188..b0f00c7 100644
--- a/libs/hwui/PathCache.h
+++ b/libs/hwui/PathCache.h
@@ -24,7 +24,6 @@
#include <utils/Vector.h>
#include "Debug.h"
-#include "Properties.h"
#include "Texture.h"
#include "utils/Macros.h"
#include "utils/Pair.h"
diff --git a/libs/hwui/ProgramCache.h b/libs/hwui/ProgramCache.h
index 38f6f99..9aadba6 100644
--- a/libs/hwui/ProgramCache.h
+++ b/libs/hwui/ProgramCache.h
@@ -25,7 +25,6 @@
#include "Debug.h"
#include "Program.h"
-#include "Properties.h"
namespace android {
namespace uirenderer {
diff --git a/libs/hwui/RenderNode.cpp b/libs/hwui/RenderNode.cpp
index 13c5499..e8f2bc0 100644
--- a/libs/hwui/RenderNode.cpp
+++ b/libs/hwui/RenderNode.cpp
@@ -33,6 +33,7 @@
#include "DisplayListLogBuffer.h"
#include "LayerRenderer.h"
#include "OpenGLRenderer.h"
+#include "TreeInfo.h"
#include "utils/MathUtils.h"
#include "renderthread/CanvasContext.h"
diff --git a/libs/hwui/RenderNode.h b/libs/hwui/RenderNode.h
index 2ce7cb7..bbe53ff 100644
--- a/libs/hwui/RenderNode.h
+++ b/libs/hwui/RenderNode.h
@@ -33,13 +33,10 @@
#include <androidfw/ResourceTypes.h>
#include "AnimatorManager.h"
-#include "DamageAccumulator.h"
#include "Debug.h"
#include "Matrix.h"
-#include "DeferredDisplayList.h"
#include "DisplayList.h"
#include "RenderProperties.h"
-#include "TreeInfo.h"
class SkBitmap;
class SkPaint;
@@ -61,6 +58,7 @@
class SaveOp;
class RestoreToCountOp;
class DrawRenderNodeOp;
+class TreeInfo;
/**
* Primary class for storing recorded canvas commands, as well as per-View/ViewGroup display properties.
diff --git a/libs/hwui/RenderProperties.h b/libs/hwui/RenderProperties.h
index b936d4b..2b5b811 100644
--- a/libs/hwui/RenderProperties.h
+++ b/libs/hwui/RenderProperties.h
@@ -26,8 +26,8 @@
#include <SkCamera.h>
#include <SkMatrix.h>
#include <SkRegion.h>
+#include <SkXfermode.h>
-#include "Animator.h"
#include "Rect.h"
#include "RevealClip.h"
#include "Outline.h"
diff --git a/libs/hwui/RenderState.h b/libs/hwui/RenderState.h
index afeef95..aa39a3a 100644
--- a/libs/hwui/RenderState.h
+++ b/libs/hwui/RenderState.h
@@ -20,15 +20,19 @@
#include <GLES2/gl2.h>
#include <GLES2/gl2ext.h>
#include <utils/Mutex.h>
+#include <utils/Functor.h>
+#include <utils/RefBase.h>
#include <private/hwui/DrawGlInfo.h>
-#include "Caches.h"
#include "utils/Macros.h"
namespace android {
namespace uirenderer {
+class Caches;
+class Layer;
+
namespace renderthread {
class CanvasContext;
class RenderThread;
diff --git a/libs/hwui/Renderer.h b/libs/hwui/Renderer.h
index 3159d1e..2b7b567 100644
--- a/libs/hwui/Renderer.h
+++ b/libs/hwui/Renderer.h
@@ -20,11 +20,12 @@
#include <SkColorFilter.h>
#include <SkPaint.h>
#include <SkRegion.h>
-
#include <utils/String8.h>
#include "AssetAtlas.h"
+class SkDrawFilter;
+
namespace android {
class Functor;
@@ -111,7 +112,7 @@
* and will not be cleared. If false, the target surface
* will be cleared
*/
- virtual status_t prepare(bool opaque) = 0;
+ virtual void prepare(bool opaque) = 0;
/**
* Prepares the renderer to draw a frame. This method must be invoked
@@ -127,14 +128,16 @@
* and will not be cleared. If false, the target surface
* will be cleared in the specified dirty rectangle
*/
- virtual status_t prepareDirty(float left, float top, float right, float bottom,
+ virtual void prepareDirty(float left, float top, float right, float bottom,
bool opaque) = 0;
/**
* Indicates the end of a frame. This method must be invoked whenever
* the caller is done rendering a frame.
+ * Returns true if any drawing was done during the frame (the output
+ * has changed / is "dirty" and should be displayed to the user).
*/
- virtual void finish() = 0;
+ virtual bool finish() = 0;
// ----------------------------------------------------------------------------
// Canvas state operations
@@ -173,58 +176,57 @@
virtual bool clipPath(const SkPath* path, SkRegion::Op op) = 0;
virtual bool clipRegion(const SkRegion* region, SkRegion::Op op) = 0;
- // Misc - should be implemented with SkPaint inspection
- virtual void resetPaintFilter() = 0;
- virtual void setupPaintFilter(int clearBits, int setBits) = 0;
+ // Misc
+ virtual void setDrawFilter(SkDrawFilter* filter) = 0;
// ----------------------------------------------------------------------------
// Canvas draw operations
// ----------------------------------------------------------------------------
- virtual status_t drawColor(int color, SkXfermode::Mode mode) = 0;
+ virtual void drawColor(int color, SkXfermode::Mode mode) = 0;
// Bitmap-based
- virtual status_t drawBitmap(const SkBitmap* bitmap, const SkPaint* paint) = 0;
- virtual status_t drawBitmap(const SkBitmap* bitmap, float srcLeft, float srcTop,
+ virtual void drawBitmap(const SkBitmap* bitmap, const SkPaint* paint) = 0;
+ virtual void drawBitmap(const SkBitmap* bitmap, float srcLeft, float srcTop,
float srcRight, float srcBottom, float dstLeft, float dstTop,
float dstRight, float dstBottom, const SkPaint* paint) = 0;
- virtual status_t drawBitmapData(const SkBitmap* bitmap, const SkPaint* paint) = 0;
- virtual status_t drawBitmapMesh(const SkBitmap* bitmap, int meshWidth, int meshHeight,
+ virtual void drawBitmapData(const SkBitmap* bitmap, const SkPaint* paint) = 0;
+ virtual void drawBitmapMesh(const SkBitmap* bitmap, int meshWidth, int meshHeight,
const float* vertices, const int* colors, const SkPaint* paint) = 0;
- virtual status_t drawPatch(const SkBitmap* bitmap, const Res_png_9patch* patch,
+ virtual void drawPatch(const SkBitmap* bitmap, const Res_png_9patch* patch,
float left, float top, float right, float bottom, const SkPaint* paint) = 0;
// Shapes
- virtual status_t drawRect(float left, float top, float right, float bottom,
+ virtual void drawRect(float left, float top, float right, float bottom,
const SkPaint* paint) = 0;
- virtual status_t drawRects(const float* rects, int count, const SkPaint* paint) = 0;
- virtual status_t drawRoundRect(float left, float top, float right, float bottom,
+ virtual void drawRects(const float* rects, int count, const SkPaint* paint) = 0;
+ virtual void drawRoundRect(float left, float top, float right, float bottom,
float rx, float ry, const SkPaint* paint) = 0;
- virtual status_t drawCircle(float x, float y, float radius, const SkPaint* paint) = 0;
- virtual status_t drawOval(float left, float top, float right, float bottom,
+ virtual void drawCircle(float x, float y, float radius, const SkPaint* paint) = 0;
+ virtual void drawOval(float left, float top, float right, float bottom,
const SkPaint* paint) = 0;
- virtual status_t drawArc(float left, float top, float right, float bottom,
+ virtual void drawArc(float left, float top, float right, float bottom,
float startAngle, float sweepAngle, bool useCenter, const SkPaint* paint) = 0;
- virtual status_t drawPath(const SkPath* path, const SkPaint* paint) = 0;
- virtual status_t drawLines(const float* points, int count, const SkPaint* paint) = 0;
- virtual status_t drawPoints(const float* points, int count, const SkPaint* paint) = 0;
+ virtual void drawPath(const SkPath* path, const SkPaint* paint) = 0;
+ virtual void drawLines(const float* points, int count, const SkPaint* paint) = 0;
+ virtual void drawPoints(const float* points, int count, const SkPaint* paint) = 0;
// Text
- virtual status_t drawText(const char* text, int bytesCount, int count, float x, float y,
+ virtual void drawText(const char* text, int bytesCount, int count, float x, float y,
const float* positions, const SkPaint* paint, float totalAdvance, const Rect& bounds,
DrawOpMode drawOpMode = kDrawOpMode_Immediate) = 0;
- virtual status_t drawTextOnPath(const char* text, int bytesCount, int count, const SkPath* path,
+ virtual void drawTextOnPath(const char* text, int bytesCount, int count, const SkPath* path,
float hOffset, float vOffset, const SkPaint* paint) = 0;
- virtual status_t drawPosText(const char* text, int bytesCount, int count,
+ virtual void drawPosText(const char* text, int bytesCount, int count,
const float* positions, const SkPaint* paint) = 0;
// ----------------------------------------------------------------------------
// Canvas draw operations - special
// ----------------------------------------------------------------------------
- virtual status_t drawRenderNode(RenderNode* renderNode, Rect& dirty,
+ virtual void drawRenderNode(RenderNode* renderNode, Rect& dirty,
int32_t replayFlags) = 0;
// TODO: rename for consistency
- virtual status_t callDrawGLFunction(Functor* functor, Rect& dirty) = 0;
+ virtual void callDrawGLFunction(Functor* functor, Rect& dirty) = 0;
}; // class Renderer
}; // namespace uirenderer
diff --git a/libs/hwui/ResourceCache.h b/libs/hwui/ResourceCache.h
index a922d53..c6cd7bf 100644
--- a/libs/hwui/ResourceCache.h
+++ b/libs/hwui/ResourceCache.h
@@ -20,17 +20,18 @@
#include <cutils/compiler.h>
#include <SkBitmap.h>
+#include <SkPath.h>
#include <utils/KeyedVector.h>
#include <utils/Singleton.h>
#include <androidfw/ResourceTypes.h>
-#include "Layer.h"
-
namespace android {
namespace uirenderer {
+class Layer;
+
/**
* Type of Resource being cached
*/
diff --git a/libs/hwui/ShadowTessellator.h b/libs/hwui/ShadowTessellator.h
index 8f19b5c..16ad91d 100644
--- a/libs/hwui/ShadowTessellator.h
+++ b/libs/hwui/ShadowTessellator.h
@@ -18,14 +18,16 @@
#ifndef ANDROID_HWUI_SHADOW_TESSELLATOR_H
#define ANDROID_HWUI_SHADOW_TESSELLATOR_H
+#include <SkPath.h>
+
#include "Debug.h"
#include "Matrix.h"
-#include "OpenGLRenderer.h"
-#include "VertexBuffer.h"
namespace android {
namespace uirenderer {
+class VertexBuffer;
+
// All SHADOW_* are used to define all the geometry property of shadows.
// Use a simplified example to illustrate the geometry setup here.
// Assuming we use 6 rays and only 1 layer, Then we will have 2 hexagons, which
diff --git a/libs/hwui/SkiaShader.cpp b/libs/hwui/SkiaShader.cpp
index c672bc4..dff19a9 100644
--- a/libs/hwui/SkiaShader.cpp
+++ b/libs/hwui/SkiaShader.cpp
@@ -21,6 +21,7 @@
#include <SkMatrix.h>
#include "Caches.h"
+#include "Extensions.h"
#include "Layer.h"
#include "Matrix.h"
#include "SkiaShader.h"
diff --git a/libs/hwui/SkiaShader.h b/libs/hwui/SkiaShader.h
index 034c3f6..e110ca5 100644
--- a/libs/hwui/SkiaShader.h
+++ b/libs/hwui/SkiaShader.h
@@ -24,16 +24,15 @@
#include <cutils/compiler.h>
-#include "Extensions.h"
-#include "ProgramCache.h"
-#include "TextureCache.h"
-#include "GradientCache.h"
+#include "Matrix.h"
namespace android {
namespace uirenderer {
class Caches;
+class Extensions;
class Layer;
+struct ProgramDescription;
/**
* Type of Skia shader in use.
diff --git a/libs/hwui/SpotShadow.cpp b/libs/hwui/SpotShadow.cpp
index e8f1b9a..0faee65 100644
--- a/libs/hwui/SpotShadow.cpp
+++ b/libs/hwui/SpotShadow.cpp
@@ -52,6 +52,7 @@
#include "ShadowTessellator.h"
#include "SpotShadow.h"
#include "Vertex.h"
+#include "VertexBuffer.h"
#include "utils/MathUtils.h"
// TODO: After we settle down the new algorithm, we can remove the old one and
diff --git a/libs/hwui/SpotShadow.h b/libs/hwui/SpotShadow.h
index e2d94f7..62a7e5d 100644
--- a/libs/hwui/SpotShadow.h
+++ b/libs/hwui/SpotShadow.h
@@ -19,11 +19,12 @@
#include "Debug.h"
#include "Vector.h"
-#include "VertexBuffer.h"
namespace android {
namespace uirenderer {
+class VertexBuffer;
+
class SpotShadow {
public:
static void createSpotShadow(bool isCasterOpaque, const Vector3& lightCenter,
diff --git a/libs/hwui/StatefulBaseRenderer.h b/libs/hwui/StatefulBaseRenderer.h
deleted file mode 100644
index 745e48a..0000000
--- a/libs/hwui/StatefulBaseRenderer.h
+++ /dev/null
@@ -1,170 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef ANDROID_HWUI_STATEFUL_BASE_RENDERER_H
-#define ANDROID_HWUI_STATEFUL_BASE_RENDERER_H
-
-#include <utils/RefBase.h>
-
-#include "Renderer.h"
-#include "Snapshot.h"
-
-namespace android {
-namespace uirenderer {
-
-/**
- * Abstract Renderer subclass, which implements Canvas state methods.
- *
- * Manages the Snapshot stack, implementing matrix, save/restore, and clipping methods in the
- * Renderer interface. Drawing and recording classes that extend StatefulBaseRenderer will have
- * different use cases:
- *
- * Drawing subclasses (i.e. OpenGLRenderer) can query attributes (such as transform) or hook into
- * changes (e.g. save/restore) with minimal surface area for manipulating the stack itself.
- *
- * Recording subclasses (i.e. DisplayListRenderer) can both record and pass through state operations
- * to StatefulBaseRenderer, so that not only will querying operations work (getClip/Matrix), but so
- * that quickRejection can also be used.
- */
-class StatefulBaseRenderer : public Renderer {
-public:
- StatefulBaseRenderer();
-
- virtual status_t prepare(bool opaque) {
- return prepareDirty(0.0f, 0.0f, mWidth, mHeight, opaque);
- }
-
- /**
- * Initialize the first snapshot, computing the projection matrix, and stores the dimensions of
- * the render target.
- */
- virtual void setViewport(int width, int height);
- void initializeSaveStack(float clipLeft, float clipTop, float clipRight, float clipBottom,
- const Vector3& lightCenter);
-
- // getters
- bool hasRectToRectTransform() const {
- return CC_LIKELY(currentTransform()->rectToRect());
- }
-
- // Save (layer)
- virtual int getSaveCount() const { return mSaveCount; }
- virtual int save(int flags);
- virtual void restore();
- virtual void restoreToCount(int saveCount);
- //virtual int saveLayer(float left, float top, float right, float bottom,
- // int alpha, SkXfermode::Mode mode, int flags);
-
- // Matrix
- virtual void getMatrix(SkMatrix* outMatrix) const;
- virtual void translate(float dx, float dy, float dz = 0.0f);
- virtual void rotate(float degrees);
- virtual void scale(float sx, float sy);
- virtual void skew(float sx, float sy);
-
- virtual void setMatrix(const SkMatrix& matrix);
- void setMatrix(const Matrix4& matrix); // internal only convenience method
- virtual void concatMatrix(const SkMatrix& matrix);
- void concatMatrix(const Matrix4& matrix); // internal only convenience method
-
- // Clip
- virtual const Rect& getLocalClipBounds() const { return mSnapshot->getLocalClip(); }
-
- virtual bool quickRejectConservative(float left, float top, float right, float bottom) const;
-
- virtual bool clipRect(float left, float top, float right, float bottom, SkRegion::Op op);
- virtual bool clipPath(const SkPath* path, SkRegion::Op op);
- virtual bool clipRegion(const SkRegion* region, SkRegion::Op op);
-
- /**
- * Does not support different clipping Ops (that is, every call to setClippingOutline is
- * effectively using SkRegion::kReplaceOp)
- *
- * The clipping outline is independent from the regular clip.
- */
- void setClippingOutline(LinearAllocator& allocator, const Outline* outline);
- void setClippingRoundRect(LinearAllocator& allocator,
- const Rect& rect, float radius, bool highPriority = true);
-
- inline const mat4* currentTransform() const {
- return mSnapshot->transform;
- }
-
-protected:
- const Rect& getRenderTargetClipBounds() const { return mSnapshot->getRenderTargetClip(); }
-
- int getWidth() { return mWidth; }
- int getHeight() { return mHeight; }
-
- // Save
- int saveSnapshot(int flags);
- void restoreSnapshot();
-
- // allows subclasses to control what value is stored in snapshot's fbo field in
- // initializeSaveStack
- virtual GLuint getTargetFbo() const {
- return -1;
- }
-
- // Clip
- bool calculateQuickRejectForScissor(float left, float top, float right, float bottom,
- bool* clipRequired, bool* roundRectClipRequired, bool snapOut) const;
-
- /**
- * Called just after a restore has occurred. The 'removed' snapshot popped from the stack,
- * 'restored' snapshot has become the top/current.
- *
- * Subclasses can override this method to handle layer restoration
- */
- virtual void onSnapshotRestored(const Snapshot& removed, const Snapshot& restored) {};
-
- virtual void onViewportInitialized() {};
-
- inline const Rect* currentClipRect() const {
- return mSnapshot->clipRect;
- }
-
- inline const Snapshot* currentSnapshot() const {
- return mSnapshot != NULL ? mSnapshot.get() : mFirstSnapshot.get();
- }
-
- inline const Snapshot* firstSnapshot() const {
- return mFirstSnapshot.get();
- }
-
- // indicites that the clip has been changed since the last time it was consumed
- bool mDirtyClip;
-
-private:
- // Dimensions of the drawing surface
- int mWidth, mHeight;
-
- // Number of saved states
- int mSaveCount;
-
- // Base state
- sp<Snapshot> mFirstSnapshot;
-
-protected:
- // Current state
- // TODO: should become private, once hooks needed by OpenGLRenderer are added
- sp<Snapshot> mSnapshot;
-}; // class StatefulBaseRenderer
-
-}; // namespace uirenderer
-}; // namespace android
-
-#endif // ANDROID_HWUI_STATEFUL_BASE_RENDERER_H
diff --git a/libs/hwui/TessellationCache.h b/libs/hwui/TessellationCache.h
index 688a699..a7c50eb 100644
--- a/libs/hwui/TessellationCache.h
+++ b/libs/hwui/TessellationCache.h
@@ -24,7 +24,6 @@
#include "Debug.h"
#include "utils/Macros.h"
#include "utils/Pair.h"
-#include "VertexBuffer.h"
class SkBitmap;
class SkCanvas;
@@ -36,6 +35,7 @@
namespace uirenderer {
class Caches;
+class VertexBuffer;
///////////////////////////////////////////////////////////////////////////////
// Classes
diff --git a/libs/hwui/TextDropShadowCache.cpp b/libs/hwui/TextDropShadowCache.cpp
index 4eec462..9e02a30 100644
--- a/libs/hwui/TextDropShadowCache.cpp
+++ b/libs/hwui/TextDropShadowCache.cpp
@@ -20,6 +20,7 @@
#include "Caches.h"
#include "Debug.h"
+#include "FontRenderer.h"
#include "TextDropShadowCache.h"
#include "Properties.h"
diff --git a/libs/hwui/TextDropShadowCache.h b/libs/hwui/TextDropShadowCache.h
index 54b930b..bb53a23 100644
--- a/libs/hwui/TextDropShadowCache.h
+++ b/libs/hwui/TextDropShadowCache.h
@@ -24,13 +24,14 @@
#include <utils/LruCache.h>
#include <utils/String16.h>
-#include "FontRenderer.h"
+#include "font/Font.h"
#include "Texture.h"
namespace android {
namespace uirenderer {
class Caches;
+class FontRenderer;
struct ShadowText {
ShadowText(): len(0), radius(0.0f), textSize(0.0f), typeface(NULL),
diff --git a/libs/hwui/TextureCache.cpp b/libs/hwui/TextureCache.cpp
index 3b8a9a4..0cd120a 100644
--- a/libs/hwui/TextureCache.cpp
+++ b/libs/hwui/TextureCache.cpp
@@ -24,6 +24,7 @@
#include <utils/Mutex.h>
#include "Caches.h"
+#include "Texture.h"
#include "TextureCache.h"
#include "Properties.h"
diff --git a/libs/hwui/TextureCache.h b/libs/hwui/TextureCache.h
index 61db5b0..668defc 100644
--- a/libs/hwui/TextureCache.h
+++ b/libs/hwui/TextureCache.h
@@ -24,11 +24,12 @@
#include <utils/Vector.h>
#include "Debug.h"
-#include "Texture.h"
namespace android {
namespace uirenderer {
+class Texture;
+
///////////////////////////////////////////////////////////////////////////////
// Defines
///////////////////////////////////////////////////////////////////////////////
diff --git a/libs/hwui/TreeInfo.h b/libs/hwui/TreeInfo.h
index ae6ea94..e820b22 100644
--- a/libs/hwui/TreeInfo.h
+++ b/libs/hwui/TreeInfo.h
@@ -20,7 +20,6 @@
#include <utils/Timers.h>
-#include "DamageAccumulator.h"
#include "utils/Macros.h"
namespace android {
@@ -30,6 +29,7 @@
class CanvasContext;
}
+class DamageAccumulator;
class OpenGLRenderer;
class RenderState;
diff --git a/libs/hwui/font/CacheTexture.cpp b/libs/hwui/font/CacheTexture.cpp
index 24ffb80..380c0ed 100644
--- a/libs/hwui/font/CacheTexture.cpp
+++ b/libs/hwui/font/CacheTexture.cpp
@@ -17,6 +17,7 @@
#include <SkGlyph.h>
#include "CacheTexture.h"
+#include "FontUtil.h"
#include "../Caches.h"
#include "../Debug.h"
#include "../Extensions.h"
diff --git a/libs/hwui/font/CacheTexture.h b/libs/hwui/font/CacheTexture.h
index 4cc4f22..a107c7a 100644
--- a/libs/hwui/font/CacheTexture.h
+++ b/libs/hwui/font/CacheTexture.h
@@ -23,7 +23,6 @@
#include <utils/Log.h>
-#include "FontUtil.h"
#include "../PixelBuffer.h"
#include "../Rect.h"
#include "../Vertex.h"
diff --git a/libs/hwui/font/CachedGlyphInfo.h b/libs/hwui/font/CachedGlyphInfo.h
index 6680a00..0642d59 100644
--- a/libs/hwui/font/CachedGlyphInfo.h
+++ b/libs/hwui/font/CachedGlyphInfo.h
@@ -19,11 +19,11 @@
#include <SkFixed.h>
-#include "CacheTexture.h"
-
namespace android {
namespace uirenderer {
+class CacheTexture;
+
struct CachedGlyphInfo {
// Has the cache been invalidated?
bool mIsValid;
diff --git a/libs/hwui/font/Font.cpp b/libs/hwui/font/Font.cpp
index ba878bac..e1df9ba 100644
--- a/libs/hwui/font/Font.cpp
+++ b/libs/hwui/font/Font.cpp
@@ -22,6 +22,7 @@
#include <utils/JenkinsHash.h>
#include <utils/Trace.h>
+#include <SkDeviceProperties.h>
#include <SkGlyph.h>
#include <SkGlyphCache.h>
#include <SkUtils.h>
@@ -41,9 +42,7 @@
///////////////////////////////////////////////////////////////////////////////
Font::Font(FontRenderer* state, const Font::FontDescription& desc) :
- mState(state), mDescription(desc) {
- mDeviceProperties = SkDeviceProperties::Make(SkDeviceProperties::Geometry::MakeDefault(), 1.0f);
-}
+ mState(state), mDescription(desc) { }
Font::FontDescription::FontDescription(const SkPaint* paint, const SkMatrix& rasterMatrix)
: mLookupTransform(rasterMatrix) {
@@ -285,7 +284,8 @@
if (cachedGlyph) {
// Is the glyph still in texture cache?
if (!cachedGlyph->mIsValid) {
- SkAutoGlyphCache autoCache(*paint, &mDeviceProperties, &mDescription.mLookupTransform);
+ SkDeviceProperties deviceProperties(kUnknown_SkPixelGeometry, 1.0f);
+ SkAutoGlyphCache autoCache(*paint, &deviceProperties, &mDescription.mLookupTransform);
const SkGlyph& skiaGlyph = GET_METRICS(autoCache.getCache(), textUnit);
updateGlyphCache(paint, skiaGlyph, autoCache.getCache(), cachedGlyph, precaching);
}
@@ -477,7 +477,8 @@
CachedGlyphInfo* newGlyph = new CachedGlyphInfo();
mCachedGlyphs.add(glyph, newGlyph);
- SkAutoGlyphCache autoCache(*paint, &mDeviceProperties, &mDescription.mLookupTransform);
+ SkDeviceProperties deviceProperties(kUnknown_SkPixelGeometry, 1.0f);
+ SkAutoGlyphCache autoCache(*paint, &deviceProperties, &mDescription.mLookupTransform);
const SkGlyph& skiaGlyph = GET_METRICS(autoCache.getCache(), glyph);
newGlyph->mIsValid = false;
newGlyph->mGlyphIndex = skiaGlyph.fID;
diff --git a/libs/hwui/font/Font.h b/libs/hwui/font/Font.h
index 0f10464..d54bc44 100644
--- a/libs/hwui/font/Font.h
+++ b/libs/hwui/font/Font.h
@@ -22,13 +22,12 @@
#include <utils/KeyedVector.h>
#include <SkScalar.h>
-#include <SkDeviceProperties.h>
#include <SkGlyphCache.h>
#include <SkScalerContext.h>
#include <SkPaint.h>
#include <SkPathMeasure.h>
-#include "CachedGlyphInfo.h"
+#include "FontUtil.h"
#include "../Rect.h"
#include "../Matrix.h"
@@ -39,6 +38,8 @@
// Font
///////////////////////////////////////////////////////////////////////////////
+class CachedGlyphInfo;
+class CacheTexture;
class FontRenderer;
/**
@@ -150,7 +151,6 @@
DefaultKeyedVector<glyph_t, CachedGlyphInfo*> mCachedGlyphs;
bool mIdentityTransform;
- SkDeviceProperties mDeviceProperties;
};
inline int strictly_order_type(const Font::FontDescription& lhs,
diff --git a/libs/hwui/renderthread/CanvasContext.cpp b/libs/hwui/renderthread/CanvasContext.cpp
index 6c3637d..8299855 100644
--- a/libs/hwui/renderthread/CanvasContext.cpp
+++ b/libs/hwui/renderthread/CanvasContext.cpp
@@ -222,24 +222,23 @@
profiler().unionDirty(&dirty);
}
- status_t status;
if (!dirty.isEmpty()) {
- status = mCanvas->prepareDirty(dirty.fLeft, dirty.fTop,
+ mCanvas->prepareDirty(dirty.fLeft, dirty.fTop,
dirty.fRight, dirty.fBottom, mOpaque);
} else {
- status = mCanvas->prepare(mOpaque);
+ mCanvas->prepare(mOpaque);
}
Rect outBounds;
- status |= mCanvas->drawRenderNode(mRootRenderNode.get(), outBounds);
+ mCanvas->drawRenderNode(mRootRenderNode.get(), outBounds);
profiler().draw(mCanvas);
- mCanvas->finish();
+ bool drew = mCanvas->finish();
profiler().markPlaybackEnd();
- if (status & DrawGlInfo::kStatusDrew) {
+ if (drew) {
swapBuffers();
} else {
mEglManager.cancelFrame();
diff --git a/libs/hwui/renderthread/EglManager.cpp b/libs/hwui/renderthread/EglManager.cpp
index 9bd6f41..e49863d 100644
--- a/libs/hwui/renderthread/EglManager.cpp
+++ b/libs/hwui/renderthread/EglManager.cpp
@@ -19,6 +19,7 @@
#include <cutils/log.h>
#include <cutils/properties.h>
+#include "../Caches.h"
#include "../RenderState.h"
#include "RenderThread.h"
diff --git a/libs/input/Android.mk b/libs/input/Android.mk
index a7fb0e2..2bbfdcc 100644
--- a/libs/input/Android.mk
+++ b/libs/input/Android.mk
@@ -27,14 +27,14 @@
libskia \
libgui \
libui \
- libinput \
- libinputflinger
+ libinput \
+ libinputflinger
LOCAL_C_INCLUDES := \
frameworks/native/services
-LOCAL_CFLAGS += -Wno-unused-parameter
+LOCAL_CFLAGS += -Wall -Werror -Wunused -Wunreachable-code
LOCAL_MODULE:= libinputservice
diff --git a/libs/input/PointerController.cpp b/libs/input/PointerController.cpp
index 9af521b..1152737 100644
--- a/libs/input/PointerController.cpp
+++ b/libs/input/PointerController.cpp
@@ -25,11 +25,14 @@
#include <cutils/log.h>
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wunused-parameter"
#include <SkBitmap.h>
#include <SkCanvas.h>
#include <SkColor.h>
#include <SkPaint.h>
#include <SkXfermode.h>
+#pragma GCC diagnostic pop
namespace android {
diff --git a/libs/input/SpriteController.cpp b/libs/input/SpriteController.cpp
index 5391393..0bc832a 100644
--- a/libs/input/SpriteController.cpp
+++ b/libs/input/SpriteController.cpp
@@ -24,11 +24,15 @@
#include <utils/String8.h>
#include <gui/Surface.h>
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wunused-parameter"
#include <SkBitmap.h>
#include <SkCanvas.h>
#include <SkColor.h>
#include <SkPaint.h>
#include <SkXfermode.h>
+#pragma GCC diagnostic pop
+
#include <android/native_window.h>
namespace android {
diff --git a/libs/storage/Android.mk b/libs/storage/Android.mk
index 7a9dd6c..fae2bf7 100644
--- a/libs/storage/Android.mk
+++ b/libs/storage/Android.mk
@@ -9,4 +9,6 @@
LOCAL_MODULE:= libstorage
+LOCAL_CFLAGS += -Wall -Werror
+
include $(BUILD_STATIC_LIBRARY)
diff --git a/libs/storage/IMountService.cpp b/libs/storage/IMountService.cpp
index 621de18..7ac7737 100644
--- a/libs/storage/IMountService.cpp
+++ b/libs/storage/IMountService.cpp
@@ -207,12 +207,19 @@
ALOGD("getStorageUsers caught exception %d\n", err);
return err;
}
- const int32_t numUsers = reply.readInt32();
+ int32_t numUsersI = reply.readInt32();
+ uint32_t numUsers;
+ if (numUsersI < 0) {
+ ALOGW("Number of users is negative: %d\n", numUsersI);
+ numUsers = 0;
+ } else {
+ numUsers = static_cast<uint32_t>(numUsersI);
+ }
*users = (int32_t*)malloc(sizeof(int32_t)*numUsers);
- for (int i = 0; i < numUsers; i++) {
+ for (size_t i = 0; i < numUsers; i++) {
**users++ = reply.readInt32();
}
- return numUsers;
+ return static_cast<int32_t>(numUsers);
}
int32_t getVolumeState(const String16& mountPoint)
@@ -546,8 +553,8 @@
}
};
-IMPLEMENT_META_INTERFACE(MountService, "IMountService");
+IMPLEMENT_META_INTERFACE(MountService, "IMountService")
// ----------------------------------------------------------------------
-};
+}
diff --git a/libs/storage/IMountServiceListener.cpp b/libs/storage/IMountServiceListener.cpp
index c98a424..11b53fd 100644
--- a/libs/storage/IMountServiceListener.cpp
+++ b/libs/storage/IMountServiceListener.cpp
@@ -34,7 +34,7 @@
onUsbMassStorageConnectionChanged(connected);
reply->writeNoException();
return NO_ERROR;
- } break;
+ }
case TRANSACTION_onStorageStateChanged: {
CHECK_INTERFACE(IMountServiceListener, data, reply);
String16 path = data.readString16();
@@ -50,4 +50,4 @@
}
// ----------------------------------------------------------------------
-};
+}
diff --git a/libs/storage/IMountShutdownObserver.cpp b/libs/storage/IMountShutdownObserver.cpp
index 1a6fdee..a74a768 100644
--- a/libs/storage/IMountShutdownObserver.cpp
+++ b/libs/storage/IMountShutdownObserver.cpp
@@ -33,11 +33,11 @@
onShutDownComplete(statusCode);
reply->writeNoException();
return NO_ERROR;
- } break;
+ }
default:
return BBinder::onTransact(code, data, reply, flags);
}
}
// ----------------------------------------------------------------------
-};
+}
diff --git a/libs/storage/IObbActionListener.cpp b/libs/storage/IObbActionListener.cpp
index eaa211e..9656e65 100644
--- a/libs/storage/IObbActionListener.cpp
+++ b/libs/storage/IObbActionListener.cpp
@@ -30,10 +30,11 @@
: BpInterface<IObbActionListener>(impl)
{ }
- virtual void onObbResult(const String16& filename, const int32_t nonce, const int32_t state) { }
+ virtual void onObbResult(const String16& /* filename */, const int32_t /* nonce */,
+ const int32_t /* state */) { }
};
-IMPLEMENT_META_INTERFACE(ObbActionListener, "IObbActionListener");
+IMPLEMENT_META_INTERFACE(ObbActionListener, "IObbActionListener")
// ----------------------------------------------------------------------
@@ -49,7 +50,7 @@
onObbResult(filename, nonce, state);
reply->writeNoException();
return NO_ERROR;
- } break;
+ }
default:
return BBinder::onTransact(code, data, reply, flags);
}
@@ -57,4 +58,4 @@
// ----------------------------------------------------------------------
-};
+}
diff --git a/libs/usb/tests/AccessoryChat/accessorychat/Android.mk b/libs/usb/tests/AccessoryChat/accessorychat/Android.mk
index 3e07155..51f2111 100644
--- a/libs/usb/tests/AccessoryChat/accessorychat/Android.mk
+++ b/libs/usb/tests/AccessoryChat/accessorychat/Android.mk
@@ -4,6 +4,7 @@
ifeq ($(HOST_OS),linux)
include $(CLEAR_VARS)
+LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
LOCAL_MODULE_TAGS := optional
@@ -21,6 +22,7 @@
# Build for device
include $(CLEAR_VARS)
+LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
LOCAL_MODULE_TAGS := optional
diff --git a/location/java/android/location/LocationRequest.java b/location/java/android/location/LocationRequest.java
index 271f2bb..39fe4ea 100644
--- a/location/java/android/location/LocationRequest.java
+++ b/location/java/android/location/LocationRequest.java
@@ -292,7 +292,7 @@
* no location sources are available), or you may receive them
* slower than requested. You may also receive them faster than
* requested (if other applications are requesting location at a
- * faster interval). The fastest rate that that you will receive
+ * faster interval). The fastest rate that you will receive
* updates can be controlled with {@link #setFastestInterval}.
*
* <p>Applications with only the coarse location permission may have their
diff --git a/media/java/android/media/MediaCodecInfo.java b/media/java/android/media/MediaCodecInfo.java
index 01f8193..f470421 100644
--- a/media/java/android/media/MediaCodecInfo.java
+++ b/media/java/android/media/MediaCodecInfo.java
@@ -207,6 +207,7 @@
// COLOR_FormatSurface indicates that the data will be a GraphicBuffer metadata reference.
// In OMX this is called OMX_COLOR_FormatAndroidOpaque.
public static final int COLOR_FormatSurface = 0x7F000789;
+ public static final int COLOR_Format32BitRGBA8888 = 0x7F00A000;
// This corresponds to YUV_420_888 format
public static final int COLOR_FormatYUV420Flexible = 0x7F420888;
public static final int COLOR_QCOM_FormatYUV420SemiPlanar = 0x7fa30c00;
diff --git a/media/java/android/media/MediaHTTPConnection.java b/media/java/android/media/MediaHTTPConnection.java
index d0f3334..b2886bb 100644
--- a/media/java/android/media/MediaHTTPConnection.java
+++ b/media/java/android/media/MediaHTTPConnection.java
@@ -31,6 +31,7 @@
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.NoRouteToHostException;
+import java.net.ProtocolException;
import java.util.HashMap;
import java.util.Map;
@@ -282,7 +283,7 @@
if (offset > 0 && response != HttpURLConnection.HTTP_PARTIAL) {
// Some servers simply ignore "Range" requests and serve
// data from the start of the content.
- throw new IOException();
+ throw new ProtocolException();
}
mInputStream =
@@ -330,6 +331,9 @@
}
return n;
+ } catch (ProtocolException e) {
+ Log.w(TAG, "readAt " + offset + " / " + size + " => " + e);
+ return MEDIA_ERROR_UNSUPPORTED;
} catch (NoRouteToHostException e) {
Log.w(TAG, "readAt " + offset + " / " + size + " => " + e);
return MEDIA_ERROR_UNSUPPORTED;
diff --git a/media/java/android/media/routing/IMediaRouteClientCallback.aidl b/media/java/android/media/routing/IMediaRouteClientCallback.aidl
new file mode 100644
index 0000000..d90ea3b
--- /dev/null
+++ b/media/java/android/media/routing/IMediaRouteClientCallback.aidl
@@ -0,0 +1,41 @@
+/* Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.media.routing;
+
+import android.media.routing.MediaRouteSelector;
+import android.media.routing.ParcelableConnectionInfo;
+import android.media.routing.ParcelableDestinationInfo;
+import android.media.routing.ParcelableRouteInfo;
+import android.os.IBinder;
+import android.os.Bundle;
+
+/**
+ * @hide
+ */
+oneway interface IMediaRouteClientCallback {
+ void onDestinationFound(int seq, in ParcelableDestinationInfo destination,
+ in ParcelableRouteInfo[] routes);
+
+ void onDestinationLost(int seq, String id);
+
+ void onDiscoveryFailed(int seq, int error, in CharSequence message, in Bundle extras);
+
+ void onConnected(int seq, in ParcelableConnectionInfo connection);
+
+ void onDisconnected(int seq);
+
+ void onConnectionFailed(int seq, int error, in CharSequence message, in Bundle extras);
+}
diff --git a/media/java/android/media/routing/IMediaRouteService.aidl b/media/java/android/media/routing/IMediaRouteService.aidl
new file mode 100644
index 0000000..493ab6d
--- /dev/null
+++ b/media/java/android/media/routing/IMediaRouteService.aidl
@@ -0,0 +1,46 @@
+/* Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.media.routing;
+
+import android.media.routing.IMediaRouteClientCallback;
+import android.media.routing.MediaRouteSelector;
+import android.os.Bundle;
+
+/**
+ * Interface to an app's MediaRouteService.
+ * @hide
+ */
+oneway interface IMediaRouteService {
+ void registerClient(int clientUid, String clientPackageName,
+ in IMediaRouteClientCallback callback);
+
+ void unregisterClient(in IMediaRouteClientCallback callback);
+
+ void startDiscovery(in IMediaRouteClientCallback callback, int seq,
+ in List<MediaRouteSelector> selectors, int flags);
+
+ void stopDiscovery(in IMediaRouteClientCallback callback);
+
+ void connect(in IMediaRouteClientCallback callback, int seq,
+ String destinationId, String routeId, int flags, in Bundle extras);
+
+ void disconnect(in IMediaRouteClientCallback callback);
+
+ void pauseStream(in IMediaRouteClientCallback callback);
+
+ void resumeStream(in IMediaRouteClientCallback callback);
+}
+
diff --git a/cmds/app_process/sigchain_proxy.cpp b/media/java/android/media/routing/IMediaRouter.aidl
similarity index 80%
rename from cmds/app_process/sigchain_proxy.cpp
rename to media/java/android/media/routing/IMediaRouter.aidl
index bb7a678..0abb258 100644
--- a/cmds/app_process/sigchain_proxy.cpp
+++ b/media/java/android/media/routing/IMediaRouter.aidl
@@ -1,5 +1,4 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
+/* Copyright (C) 2014 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,4 +13,10 @@
* limitations under the License.
*/
-#include "sigchainlib/sigchain.cc"
+package android.media.routing;
+
+/** @hide */
+interface IMediaRouter {
+
+}
+
diff --git a/cmds/app_process/sigchain_proxy.cpp b/media/java/android/media/routing/IMediaRouterDelegate.aidl
similarity index 79%
copy from cmds/app_process/sigchain_proxy.cpp
copy to media/java/android/media/routing/IMediaRouterDelegate.aidl
index bb7a678..35f84c8 100644
--- a/cmds/app_process/sigchain_proxy.cpp
+++ b/media/java/android/media/routing/IMediaRouterDelegate.aidl
@@ -1,5 +1,4 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
+/* Copyright (C) 2014 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,4 +13,10 @@
* limitations under the License.
*/
-#include "sigchainlib/sigchain.cc"
+package android.media.routing;
+
+/** @hide */
+interface IMediaRouterDelegate {
+
+}
+
diff --git a/cmds/app_process/sigchain_proxy.cpp b/media/java/android/media/routing/IMediaRouterRoutingCallback.aidl
similarity index 78%
copy from cmds/app_process/sigchain_proxy.cpp
copy to media/java/android/media/routing/IMediaRouterRoutingCallback.aidl
index bb7a678..173ae55 100644
--- a/cmds/app_process/sigchain_proxy.cpp
+++ b/media/java/android/media/routing/IMediaRouterRoutingCallback.aidl
@@ -1,5 +1,4 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
+/* Copyright (C) 2014 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,4 +13,10 @@
* limitations under the License.
*/
-#include "sigchainlib/sigchain.cc"
+package android.media.routing;
+
+/** @hide */
+interface IMediaRouterRoutingCallback {
+
+}
+
diff --git a/cmds/app_process/sigchain_proxy.cpp b/media/java/android/media/routing/IMediaRouterStateCallback.aidl
similarity index 79%
copy from cmds/app_process/sigchain_proxy.cpp
copy to media/java/android/media/routing/IMediaRouterStateCallback.aidl
index bb7a678..0299904 100644
--- a/cmds/app_process/sigchain_proxy.cpp
+++ b/media/java/android/media/routing/IMediaRouterStateCallback.aidl
@@ -1,5 +1,4 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
+/* Copyright (C) 2014 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,4 +13,10 @@
* limitations under the License.
*/
-#include "sigchainlib/sigchain.cc"
+package android.media.routing;
+
+/** @hide */
+interface IMediaRouterStateCallback {
+
+}
+
diff --git a/media/java/android/media/routing/MediaRouteSelector.aidl b/media/java/android/media/routing/MediaRouteSelector.aidl
new file mode 100644
index 0000000..37bfa4a
--- /dev/null
+++ b/media/java/android/media/routing/MediaRouteSelector.aidl
@@ -0,0 +1,18 @@
+/* Copyright 2014, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+
+package android.media.routing;
+
+parcelable MediaRouteSelector;
diff --git a/media/java/android/media/routing/MediaRouteSelector.java b/media/java/android/media/routing/MediaRouteSelector.java
new file mode 100644
index 0000000..26a9b1c
--- /dev/null
+++ b/media/java/android/media/routing/MediaRouteSelector.java
@@ -0,0 +1,357 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.media.routing;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.media.routing.MediaRouter.RouteFeatures;
+import android.os.Bundle;
+import android.os.IInterface;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.text.TextUtils;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * A media route selector consists of a set of constraints that are used to select
+ * the routes to which an application would like to connect. The constraints consist
+ * of a set of required or optional features and protocols. The constraints may also
+ * require the use of a specific media route service package or additional characteristics
+ * that are described by a bundle of extra parameters.
+ * <p>
+ * The application will typically create several different selectors that express
+ * various combinations of characteristics that it would like to use together when
+ * it connects to a destination media device. For each destination that is discovered,
+ * media route services will publish some number of routes and include information
+ * about which selector each route matches. The application will then choose among
+ * these routes to determine which best satisfies its desired purpose and connect to it.
+ * </p>
+ */
+public final class MediaRouteSelector implements Parcelable {
+ private final int mRequiredFeatures;
+ private final int mOptionalFeatures;
+ private final List<String> mRequiredProtocols;
+ private final List<String> mOptionalProtocols;
+ private final String mServicePackageName;
+ private final Bundle mExtras;
+
+ MediaRouteSelector(int requiredFeatures, int optionalFeatures,
+ List<String> requiredProtocols, List<String> optionalProtocols,
+ String servicePackageName, Bundle extras) {
+ mRequiredFeatures = requiredFeatures;
+ mOptionalFeatures = optionalFeatures;
+ mRequiredProtocols = requiredProtocols;
+ mOptionalProtocols = optionalProtocols;
+ mServicePackageName = servicePackageName;
+ mExtras = extras;
+ }
+
+ /**
+ * Gets the set of required route features.
+ *
+ * @return A set of required route feature flags.
+ */
+ public @RouteFeatures int getRequiredFeatures() {
+ return mRequiredFeatures;
+ }
+
+ /**
+ * Gets the set of optional route features.
+ *
+ * @return A set of optional route feature flags.
+ */
+ public @RouteFeatures int getOptionalFeatures() {
+ return mOptionalFeatures;
+ }
+
+ /**
+ * Gets the list of route protocols that a route must support in order to be selected.
+ * <p>
+ * Refer to <code>android.support.media.protocols.MediaRouteProtocol</code>
+ * for more information.
+ * </p>
+ *
+ * @return The list of fully qualified route protocol names.
+ */
+ public @NonNull List<String> getRequiredProtocols() {
+ return mRequiredProtocols;
+ }
+
+ /**
+ * Gets the list of optional route protocols that a client may use if they are available.
+ * <p>
+ * Refer to <code>android.support.media.protocols.MediaRouteProtocol</code>
+ * for more information.
+ * </p>
+ *
+ * @return The list of optional fully qualified route protocol names.
+ */
+ public @NonNull List<String> getOptionalProtocols() {
+ return mOptionalProtocols;
+ }
+
+ /**
+ * Returns true if the selector includes a required or optional request for
+ * the specified protocol using its fully qualified class name.
+ * <p>
+ * Refer to <code>android.support.media.protocols.MediaRouteProtocol</code>
+ * for more information.
+ * </p>
+ *
+ * @param clazz The protocol class.
+ * @return True if the protocol was requested.
+ */
+ public boolean containsProtocol(@NonNull Class<?> clazz) {
+ return containsProtocol(clazz.getName());
+ }
+
+ /**
+ * Returns true if the selector includes a required or optional request for
+ * the specified protocol.
+ * <p>
+ * Refer to <code>android.support.media.protocols.MediaRouteProtocol</code>
+ * for more information.
+ * </p>
+ *
+ * @param name The name of the protocol.
+ * @return True if the protocol was requested.
+ */
+ public boolean containsProtocol(@NonNull String name) {
+ return mRequiredProtocols.contains(name)
+ || mOptionalProtocols.contains(name);
+ }
+
+ /**
+ * Gets the package name of a specific media route service that this route selector
+ * requires.
+ *
+ * @return The required media route service package name, or null if none.
+ */
+ public @Nullable String getServicePackageName() {
+ return mServicePackageName;
+ }
+
+ /**
+ * Gets optional extras that may be used to select or configure routes for a
+ * particular purpose. Some extras may be used by media route services to apply
+ * additional constraints or parameters for the routes to be discovered.
+ *
+ * @return The optional extras, or null if none.
+ */
+ public @Nullable Bundle getExtras() {
+ return mExtras;
+ }
+
+ @Override
+ public String toString() {
+ return "MediaRouteSelector{ "
+ + ", requiredFeatures=0x" + Integer.toHexString(mRequiredFeatures)
+ + ", optionalFeatures=0x" + Integer.toHexString(mOptionalFeatures)
+ + ", requiredProtocols=" + mRequiredProtocols
+ + ", optionalProtocols=" + mOptionalProtocols
+ + ", servicePackageName=" + mServicePackageName
+ + ", extras=" + mExtras + " }";
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ dest.writeInt(mRequiredFeatures);
+ dest.writeInt(mOptionalFeatures);
+ dest.writeStringList(mRequiredProtocols);
+ dest.writeStringList(mOptionalProtocols);
+ dest.writeString(mServicePackageName);
+ dest.writeBundle(mExtras);
+ }
+
+ public static final Parcelable.Creator<MediaRouteSelector> CREATOR =
+ new Parcelable.Creator<MediaRouteSelector>() {
+ @Override
+ public MediaRouteSelector createFromParcel(Parcel source) {
+ int requiredFeatures = source.readInt();
+ int optionalFeatures = source.readInt();
+ ArrayList<String> requiredProtocols = new ArrayList<String>();
+ ArrayList<String> optionalProtocols = new ArrayList<String>();
+ source.readStringList(requiredProtocols);
+ source.readStringList(optionalProtocols);
+ return new MediaRouteSelector(requiredFeatures, optionalFeatures,
+ requiredProtocols, optionalProtocols,
+ source.readString(), source.readBundle());
+ }
+
+ @Override
+ public MediaRouteSelector[] newArray(int size) {
+ return new MediaRouteSelector[size];
+ }
+ };
+
+ /**
+ * Builder for {@link MediaRouteSelector} objects.
+ */
+ public static final class Builder {
+ private int mRequiredFeatures;
+ private int mOptionalFeatures;
+ private final ArrayList<String> mRequiredProtocols = new ArrayList<String>();
+ private final ArrayList<String> mOptionalProtocols = new ArrayList<String>();
+ private String mServicePackageName;
+ private Bundle mExtras;
+
+ /**
+ * Creates an initially empty selector builder.
+ */
+ public Builder() {
+ }
+
+ /**
+ * Sets the set of required route features.
+ *
+ * @param features A set of required route feature flags.
+ */
+ public @NonNull Builder setRequiredFeatures(@RouteFeatures int features) {
+ mRequiredFeatures = features;
+ return this;
+ }
+
+ /**
+ * Sets the set of optional route features.
+ *
+ * @param features A set of optional route feature flags.
+ */
+ public @NonNull Builder setOptionalFeatures(@RouteFeatures int features) {
+ mOptionalFeatures = features;
+ return this;
+ }
+
+ /**
+ * Adds a route protocol that a route must support in order to be selected
+ * using its fully qualified class name.
+ * <p>
+ * Refer to <code>android.support.media.protocols.MediaRouteProtocol</code>
+ * for more information.
+ * </p>
+ *
+ * @param clazz The protocol class.
+ * @return this
+ */
+ public @NonNull Builder addRequiredProtocol(@NonNull Class<?> clazz) {
+ if (clazz == null) {
+ throw new IllegalArgumentException("clazz must not be null");
+ }
+ return addRequiredProtocol(clazz.getName());
+ }
+
+ /**
+ * Adds a route protocol that a route must support in order to be selected.
+ * <p>
+ * Refer to <code>android.support.media.protocols.MediaRouteProtocol</code>
+ * for more information.
+ * </p>
+ *
+ * @param name The fully qualified name of the required protocol.
+ * @return this
+ */
+ public @NonNull Builder addRequiredProtocol(@NonNull String name) {
+ if (TextUtils.isEmpty(name)) {
+ throw new IllegalArgumentException("name must not be null or empty");
+ }
+ mRequiredProtocols.add(name);
+ return this;
+ }
+
+ /**
+ * Adds an optional route protocol that a client may use if available
+ * using its fully qualified class name.
+ * <p>
+ * Refer to <code>android.support.media.protocols.MediaRouteProtocol</code>
+ * for more information.
+ * </p>
+ *
+ * @param clazz The protocol class.
+ * @return this
+ */
+ public @NonNull Builder addOptionalProtocol(@NonNull Class<?> clazz) {
+ if (clazz == null) {
+ throw new IllegalArgumentException("clazz must not be null");
+ }
+ return addOptionalProtocol(clazz.getName());
+ }
+
+ /**
+ * Adds an optional route protocol that a client may use if available.
+ * <p>
+ * Refer to <code>android.support.media.protocols.MediaRouteProtocol</code>
+ * for more information.
+ * </p>
+ *
+ * @param name The fully qualified name of the optional protocol.
+ * @return this
+ */
+ public @NonNull Builder addOptionalProtocol(@NonNull String name) {
+ if (TextUtils.isEmpty(name)) {
+ throw new IllegalArgumentException("name must not be null or empty");
+ }
+ mOptionalProtocols.add(name);
+ return this;
+ }
+
+ /**
+ * Sets the package name of the media route service to which this selector
+ * appertains.
+ * <p>
+ * If a package name is specified here then this selector will only be
+ * passed to media route services from that package. This has the effect
+ * of restricting the set of matching routes to just those that are offered
+ * by that package.
+ * </p>
+ *
+ * @param packageName The required service package name, or null if none.
+ * @return this
+ */
+ public @NonNull Builder setServicePackageName(@Nullable String packageName) {
+ mServicePackageName = packageName;
+ return this;
+ }
+
+ /**
+ * Sets optional extras that may be used to select or configure routes for a
+ * particular purpose. Some extras may be used by route services to specify
+ * additional constraints or parameters for the routes to be discovered.
+ *
+ * @param extras The optional extras, or null if none.
+ * @return this
+ */
+ public @NonNull Builder setExtras(@Nullable Bundle extras) {
+ mExtras = extras;
+ return this;
+ }
+
+ /**
+ * Builds the {@link MediaRouteSelector} object.
+ *
+ * @return The new media route selector instance.
+ */
+ public @NonNull MediaRouteSelector build() {
+ return new MediaRouteSelector(mRequiredFeatures, mOptionalFeatures,
+ mRequiredProtocols, mOptionalProtocols, mServicePackageName, mExtras);
+ }
+ }
+}
diff --git a/media/java/android/media/routing/MediaRouteService.java b/media/java/android/media/routing/MediaRouteService.java
new file mode 100644
index 0000000..4d5a8a9
--- /dev/null
+++ b/media/java/android/media/routing/MediaRouteService.java
@@ -0,0 +1,1023 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.media.routing;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.SdkConstant;
+import android.app.Service;
+import android.content.Intent;
+import android.content.pm.PackageManager.NameNotFoundException;
+import android.media.routing.MediaRouter.ConnectionError;
+import android.media.routing.MediaRouter.ConnectionInfo;
+import android.media.routing.MediaRouter.ConnectionRequest;
+import android.media.routing.MediaRouter.DestinationInfo;
+import android.media.routing.MediaRouter.DiscoveryError;
+import android.media.routing.MediaRouter.DiscoveryRequest;
+import android.media.routing.MediaRouter.RouteInfo;
+import android.media.routing.MediaRouter.ServiceMetadata;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.RemoteException;
+import android.util.ArrayMap;
+import android.util.Log;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Media route services implement strategies for discovering
+ * and establishing connections to media devices and their routes. These services
+ * are also known as media route providers.
+ * <p>
+ * Each media route service subclass is responsible for enabling applications
+ * and the system to interact with media devices of some kind.
+ * For example, one particular media route service implementation might
+ * offer support for discovering nearby wireless display devices and streaming
+ * video contents to them; another media route service implementation might
+ * offer support for discovering nearby speakers and streaming media appliances
+ * and sending commands to play content on request.
+ * </p><p>
+ * Subclasses must override the {@link #onCreateClientSession} method to return
+ * a {@link ClientSession} object that implements the {@link ClientSession#onStartDiscovery},
+ * {@link ClientSession#onStopDiscovery}, and {@link ClientSession#onConnect} methods
+ * to allow clients to discover and connect to media devices.
+ * </p><p>
+ * This object is not thread-safe. All callbacks are invoked on the main looper.
+ * </p>
+ *
+ * <h3>Clients</h3>
+ * <p>
+ * The clients of this API are media applications that would like to discover
+ * and connect to media devices. The client may also be the system, such as
+ * when the user initiates display mirroring via the Cast Screen function.
+ * </p><p>
+ * There may be multiple client sessions active at the same time. Each client
+ * session can request discovery and connect to routes independently of any
+ * other client. It is the responsibility of the media route service to maintain
+ * separate state for each client session and to ensure that clients cannot interfere
+ * with one another in harmful ways.
+ * </p><p>
+ * Notwithstanding the requirement to support any number of concurrent client
+ * sessions, the media route service may impose constraints on how many clients
+ * can connect to the same media device in a particular mode at the same time.
+ * In some cases, media devices may support connections from an arbitrary number
+ * of clients simultaneously but often it may be necessary to ensure that only
+ * one client is in control. When this happens, the media route service should
+ * report a connection error unless the connection request specifies that the
+ * client should take control of the media device (and forcibly disconnect other
+ * clients that may be using it).
+ * </p>
+ *
+ * <h3>Destinations</h3>
+ * <p>
+ * The media devices to which an application may send media content are referred
+ * to in the API as destinations. Each destination therefore represents a single
+ * independent device such as a speaker or TV set. Destinations are given meaningful
+ * names and descriptions to help the user associate them with devices in their
+ * environment.
+ * </p><p>
+ * Destinations may be local or remote and may be accessed through various means,
+ * often wirelessly. The user may install media route services to enable
+ * media applications to connect to a variety of destinations with different
+ * capabilities.
+ * </p>
+ *
+ * <h3>Routes</h3>
+ * <p>
+ * Routes represent possible usages or means of reaching and interacting with
+ * a destination. Since destinations may support many different features, they may
+ * each offer multiple routes for applications to choose from based on their needs.
+ * For example, one route might express the ability to stream locally rendered audio
+ * and video to the device; another route might express the ability to send a URL for
+ * the destination to download from the network and play all by itself.
+ * </p><p>
+ * Routes are discovered according to the set of capabilities that
+ * an application or the system is seeking to use at a particular time. For example,
+ * if an application wants to stream music to a destination then it will ask the
+ * {@link MediaRouter} to find routes to destinations can stream music and ignore
+ * all other destinations that cannot.
+ * </p><p>
+ * In general, the application will inspect the set of routes that have been
+ * offered then connect to the most appropriate route for its desired purpose.
+ * </p>
+ *
+ * <h3>Discovery</h3>
+ * <p>
+ * Discovery is the process of finding destinations based on a description of the
+ * kinds of routes that an application or the system would like to use.
+ * </p><p>
+ * Discovery begins when {@link ClientSession#onStartDiscovery} is called and ends when
+ * {@link ClientSession#onStopDiscovery} is called. There may be multiple simultaneous
+ * discovery requests in progress at the same time from different clients. It is up to
+ * the media route service to perform these requests in parallel or multiplex them
+ * as required.
+ * </p><p>
+ * Media route services are <em>strongly encouraged</em> to use the information
+ * in the discovery request to optimize discovery and avoid redundant work.
+ * In the case where no media device supported by the media route service
+ * could possibly offer the requested capabilities, the
+ * {@link ClientSession#onStartDiscovery} method should return <code>false</code> to
+ * let the system know that it can unbind from the media route service and
+ * release its resources.
+ * </p>
+ *
+ * <h3>Settings</h3>
+ * <p>
+ * Many kinds of devices can be discovered on demand simply by scanning the local network
+ * or using wireless protocols such as Bluetooth to find them. However, in some cases
+ * it may be necessary for the user to manually configure destinations before they
+ * can be used (or to adjust settings later). Actual user configuration of destinations
+ * is beyond the scope of this API but media route services may specify an activity
+ * in their manifest that the user can launch to perform these tasks.
+ * </p><p>
+ * Note that media route services that are installed from the store must be enabled
+ * by the user before they become available for applications to use.
+ * The {@link android.provider.Settings#ACTION_CAST_SETTINGS Settings.ACTION_CAST_SETTINGS}
+ * settings activity provides the ability for the user to configure media route services.
+ * </p>
+ *
+ * <h3>Manifest Declaration</h3>
+ * <p>
+ * Media route services must be declared in the manifest along with meta-data
+ * about the kinds of routes that they are capable of discovering. The system
+ * uses this information to optimize the set of services to which it binds in
+ * order to satisfy a particular discovery request.
+ * </p><p>
+ * To extend this class, you must declare the service in your manifest file with
+ * the {@link android.Manifest.permission#BIND_MEDIA_ROUTE_SERVICE} permission
+ * and include an intent filter with the {@link #SERVICE_INTERFACE} action. You must
+ * also add meta-data to describe the kinds of routes that your service is capable
+ * of discovering.
+ * </p><p>
+ * For example:
+ * </p><pre>
+ * <service android:name=".MediaRouteProvider"
+ * android:label="@string/service_name"
+ * android:permission="android.permission.BIND_MEDIA_ROUTE_SERVICE">
+ * <intent-filter>
+ * <action android:name="android.media.routing.MediaRouteService" />
+ * </intent-filter>
+ *
+ * TODO: INSERT METADATA DECLARATIONS HERE
+ *
+ * </service>
+ * </pre>
+ */
+public abstract class MediaRouteService extends Service {
+ private static final String TAG = "MediaRouteService";
+
+ private static final boolean DEBUG = true;
+
+ private final Handler mHandler;
+ private final BinderService mService;
+ private final ArrayMap<IBinder, ClientRecord> mClientRecords =
+ new ArrayMap<IBinder, ClientRecord>();
+
+ private ServiceMetadata mMetadata;
+
+ /**
+ * The {@link Intent} that must be declared as handled by the service.
+ */
+ @SdkConstant(SdkConstant.SdkConstantType.SERVICE_ACTION)
+ public static final String SERVICE_INTERFACE =
+ "android.media.routing.MediaRouteService";
+
+ /**
+ * Creates a media route service.
+ */
+ public MediaRouteService() {
+ mHandler = new Handler(true);
+ mService = new BinderService();
+ }
+
+ @Override
+ public @Nullable IBinder onBind(Intent intent) {
+ if (SERVICE_INTERFACE.equals(intent.getAction())) {
+ return mService;
+ }
+ return null;
+ }
+
+ /**
+ * Creates a new client session on behalf of a client.
+ * <p>
+ * The implementation should return a {@link ClientSession} for the client
+ * to use. The media route service must take care to manage the state of
+ * each client session independently from any others that might also be
+ * in use at the same time.
+ * </p>
+ *
+ * @param client Information about the client.
+ * @return The client session object, or null if the client is not allowed
+ * to interact with this media route service.
+ */
+ public abstract @Nullable ClientSession onCreateClientSession(@NonNull ClientInfo client);
+
+ /**
+ * Gets metadata about this service.
+ * <p>
+ * Use this method to obtain a {@link ServiceMetadata} object to provide when creating
+ * a {@link android.media.routing.MediaRouter.DestinationInfo.Builder}.
+ * </p>
+ *
+ * @return Metadata about this service.
+ */
+ public @NonNull ServiceMetadata getServiceMetadata() {
+ if (mMetadata == null) {
+ try {
+ mMetadata = new ServiceMetadata(this);
+ } catch (NameNotFoundException ex) {
+ Log.wtf(TAG, "Could not retrieve own service metadata!");
+ }
+ }
+ return mMetadata;
+ }
+
+ /**
+ * Enables a single client to access the functionality of the media route service.
+ */
+ public static abstract class ClientSession {
+ /**
+ * Starts discovery.
+ * <p>
+ * If the media route service is capable of discovering routes that satisfy
+ * the request then this method should start discovery and return true.
+ * Otherwise, this method should return false. If false is returned,
+ * then the framework will not call {@link #onStopDiscovery} since discovery
+ * was never actually started.
+ * </p><p>
+ * There may already be other discovery requests in progress at the same time
+ * for other clients; the media route service must keep track of them all.
+ * </p>
+ *
+ * @param req The discovery request to start.
+ * @param callback A callback to receive discovery events related to this
+ * particular request. The events that the service sends to this callback
+ * will be sent to the client that initiated the discovery request.
+ * @return True if discovery has started. False if the media route service
+ * is unable to discover routes that satisfy the request.
+ */
+ public abstract boolean onStartDiscovery(@NonNull DiscoveryRequest req,
+ @NonNull DiscoveryCallback callback);
+
+ /**
+ * Stops discovery.
+ * <p>
+ * If {@link #onStartDiscovery} returned true, then this method will eventually
+ * be called when the framework no longer requires this discovery request
+ * to be performed.
+ * </p><p>
+ * There may still be other discovery requests in progress for other clients;
+ * they must keep working until they have each been stopped by their client.
+ * </p>
+ */
+ public abstract void onStopDiscovery();
+
+ /**
+ * Starts connecting to a route.
+ *
+ * @param req The connection request.
+ * @param callback A callback to receive events connection events related
+ * to this particular request. The events that the service sends to this callback
+ * will be sent to the client that initiated the discovery request.
+ * @return True if the connection is in progress, or false if the client
+ * unable to connect to the requested route.
+ */
+ public abstract boolean onConnect(@NonNull ConnectionRequest req,
+ @NonNull ConnectionCallback callback);
+
+ /**
+ * Called when the client requests to disconnect from the route
+ * or abort a connection attempt in progress.
+ */
+ public abstract void onDisconnect();
+
+ /**
+ * Called when the client requests to pause streaming of content to
+ * live audio/video routes such as when it goes into the background.
+ * <p>
+ * The default implementation does nothing.
+ * </p>
+ */
+ public void onPauseStream() { }
+
+ /**
+ * Called when the application requests to resume streaming of content to
+ * live audio/video routes such as when it returns to the foreground.
+ * <p>
+ * The default implementation does nothing.
+ * </p>
+ */
+ public void onResumeStream() { }
+
+ /**
+ * Called when the client is releasing the session.
+ * <p>
+ * The framework automatically takes care of stopping discovery and
+ * terminating the connection politely before calling this method to release
+ * the session.
+ * </p><p>
+ * The default implementation does nothing.
+ * </p>
+ */
+ public void onRelease() { }
+ }
+
+ /**
+ * Provides events in response to a discovery request.
+ */
+ public final class DiscoveryCallback {
+ private final ClientRecord mRecord;
+
+ DiscoveryCallback(ClientRecord record) {
+ mRecord = record;
+ }
+
+ /**
+ * Called by the service when a destination is found that
+ * offers one or more routes that satisfy the discovery request.
+ * <p>
+ * This method should be called whenever the list of available routes
+ * at a destination changes or whenever the properties of the destination
+ * itself change.
+ * </p>
+ *
+ * @param destination The destination that was found.
+ * @param routes The list of that destination's routes that satisfy the
+ * discovery request.
+ */
+ public void onDestinationFound(final @NonNull DestinationInfo destination,
+ final @NonNull List<RouteInfo> routes) {
+ if (destination == null) {
+ throw new IllegalArgumentException("destination must not be null");
+ }
+ if (routes == null) {
+ throw new IllegalArgumentException("routes must not be null");
+ }
+ for (int i = 0; i < routes.size(); i++) {
+ if (routes.get(i).getDestination() != destination) {
+ throw new IllegalArgumentException("routes must refer to the "
+ + "destination");
+ }
+ }
+
+ mHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ mRecord.dispatchDestinationFound(DiscoveryCallback.this,
+ destination, routes);
+ }
+ });
+ }
+
+ /**
+ * Called by the service when a destination is no longer
+ * reachable or is no longer offering any routes that satisfy
+ * the discovery request.
+ *
+ * @param destination The destination that went away.
+ */
+ public void onDestinationLost(final @NonNull DestinationInfo destination) {
+ if (destination == null) {
+ throw new IllegalArgumentException("destination must not be null");
+ }
+
+ mHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ mRecord.dispatchDestinationLost(DiscoveryCallback.this, destination);
+ }
+ });
+ }
+
+ /**
+ * Called by the service when a discovery has failed in a non-recoverable manner.
+ *
+ * @param error The error code: one of
+ * {@link MediaRouter#DISCOVERY_ERROR_UNKNOWN},
+ * {@link MediaRouter#DISCOVERY_ERROR_ABORTED},
+ * or {@link MediaRouter#DISCOVERY_ERROR_NO_CONNECTIVITY}.
+ * @param message The localized error message, or null if none. This message
+ * may be shown to the user.
+ * @param extras Additional information about the error which a client
+ * may use, or null if none.
+ */
+ public void onDiscoveryFailed(final @DiscoveryError int error,
+ final @Nullable CharSequence message, final @Nullable Bundle extras) {
+ mHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ mRecord.dispatchDiscoveryFailed(DiscoveryCallback.this,
+ error, message, extras);
+ }
+ });
+ }
+ }
+
+ /**
+ * Provides events in response to a connection request.
+ */
+ public final class ConnectionCallback {
+ private final ClientRecord mRecord;
+
+ ConnectionCallback(ClientRecord record) {
+ mRecord = record;
+ }
+
+ /**
+ * Called by the service when the connection succeeds.
+ *
+ * @param connection Immutable information about the connection.
+ */
+ public void onConnected(final @NonNull ConnectionInfo connection) {
+ if (connection == null) {
+ throw new IllegalArgumentException("connection must not be null");
+ }
+
+ mHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ mRecord.dispatchConnected(ConnectionCallback.this, connection);
+ }
+ });
+ }
+
+ /**
+ * Called by the service when the connection is terminated normally.
+ * <p>
+ * Abnormal termination is reported via {@link #onConnectionFailed}.
+ * </p>
+ */
+ public void onDisconnected() {
+ mHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ mRecord.dispatchDisconnected(ConnectionCallback.this);
+ }
+ });
+ }
+
+ /**
+ * Called by the service when a connection attempt or connection in
+ * progress has failed in a non-recoverable manner.
+ *
+ * @param error The error code: one of
+ * {@link MediaRouter#CONNECTION_ERROR_ABORTED},
+ * {@link MediaRouter#CONNECTION_ERROR_UNAUTHORIZED},
+ * {@link MediaRouter#CONNECTION_ERROR_UNREACHABLE},
+ * {@link MediaRouter#CONNECTION_ERROR_BUSY},
+ * {@link MediaRouter#CONNECTION_ERROR_TIMEOUT},
+ * {@link MediaRouter#CONNECTION_ERROR_BROKEN},
+ * or {@link MediaRouter#CONNECTION_ERROR_BARGED}.
+ * @param message The localized error message, or null if none. This message
+ * may be shown to the user.
+ * @param extras Additional information about the error which a client
+ * may use, or null if none.
+ */
+ public void onConnectionFailed(final @ConnectionError int error,
+ final @Nullable CharSequence message, final @Nullable Bundle extras) {
+ mHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ mRecord.dispatchConnectionFailed(ConnectionCallback.this,
+ error, message, extras);
+ }
+ });
+ }
+ }
+
+ /**
+ * Identifies a client of the media route service.
+ */
+ public static final class ClientInfo {
+ private final int mUid;
+ private final String mPackageName;
+
+ ClientInfo(int uid, String packageName) {
+ mUid = uid;
+ mPackageName = packageName;
+ }
+
+ /**
+ * Gets the UID of the client application.
+ */
+ public int getUid() {
+ return mUid;
+ }
+
+ /**
+ * Gets the package name of the client application.
+ */
+ public @NonNull String getPackageName() {
+ return mPackageName;
+ }
+
+ @Override
+ public @NonNull String toString() {
+ return "ClientInfo{ uid=" + mUid + ", package=" + mPackageName + " }";
+ }
+ }
+
+ private final class BinderService extends IMediaRouteService.Stub {
+ @Override
+ public void registerClient(final int clientUid, final String clientPackageName,
+ final IMediaRouteClientCallback callback) {
+ mHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ ClientInfo client = new ClientInfo(clientUid, clientPackageName);
+ if (DEBUG) {
+ Log.d(TAG, "registerClient: client=" + client);
+ }
+
+ ClientSession session = onCreateClientSession(client);
+ if (session == null) {
+ // request refused by service
+ Log.w(TAG, "Media route service refused to create session for client: "
+ + "client=" + client);
+ return;
+ }
+
+ ClientRecord record = new ClientRecord(callback, client, session);
+ try {
+ callback.asBinder().linkToDeath(record, 0);
+ } catch (RemoteException ex) {
+ // client died prematurely
+ Log.w(TAG, "Client died prematurely while creating session: "
+ + "client=" + client);
+ record.release();
+ return;
+ }
+
+ mClientRecords.put(callback.asBinder(), record);
+ }
+ });
+ }
+
+ @Override
+ public void unregisterClient(IMediaRouteClientCallback callback) {
+ unregisterClient(callback, false);
+ }
+
+ void unregisterClient(final IMediaRouteClientCallback callback,
+ final boolean died) {
+ mHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ ClientRecord record = mClientRecords.remove(callback.asBinder());
+ if (record == null) {
+ return; // spurious
+ }
+
+ if (DEBUG) {
+ Log.d(TAG, "unregisterClient: client=" + record.getClientInfo()
+ + ", died=" + died);
+ }
+
+ record.release();
+ callback.asBinder().unlinkToDeath(record, 0);
+ }
+ });
+ }
+
+ @Override
+ public void startDiscovery(final IMediaRouteClientCallback callback,
+ final int seq, final List<MediaRouteSelector> selectors,
+ final int flags) {
+ mHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ ClientRecord record = mClientRecords.get(callback.asBinder());
+ if (record == null) {
+ return; // spurious
+ }
+
+ if (DEBUG) {
+ Log.d(TAG, "startDiscovery: client=" + record.getClientInfo()
+ + ", seq=" + seq + ", selectors=" + selectors
+ + ", flags=0x" + Integer.toHexString(flags));
+ }
+ record.startDiscovery(seq, selectors, flags);
+ }
+ });
+ }
+
+ @Override
+ public void stopDiscovery(final IMediaRouteClientCallback callback) {
+ mHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ ClientRecord record = mClientRecords.get(callback.asBinder());
+ if (record == null) {
+ return; // spurious
+ }
+
+ if (DEBUG) {
+ Log.d(TAG, "stopDiscovery: client=" + record.getClientInfo());
+ }
+ record.stopDiscovery();
+ }
+ });
+ }
+
+ @Override
+ public void connect(final IMediaRouteClientCallback callback,
+ final int seq, final String destinationId, final String routeId,
+ final int flags, final Bundle extras) {
+ mHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ ClientRecord record = mClientRecords.get(callback.asBinder());
+ if (record == null) {
+ return; // spurious
+ }
+
+ if (DEBUG) {
+ Log.d(TAG, "connect: client=" + record.getClientInfo()
+ + ", seq=" + seq + ", destinationId=" + destinationId
+ + ", routeId=" + routeId
+ + ", flags=0x" + Integer.toHexString(flags)
+ + ", extras=" + extras);
+ }
+ record.connect(seq, destinationId, routeId, flags, extras);
+ }
+ });
+ }
+
+ @Override
+ public void disconnect(final IMediaRouteClientCallback callback) {
+ mHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ ClientRecord record = mClientRecords.get(callback.asBinder());
+ if (record == null) {
+ return; // spurious
+ }
+
+ if (DEBUG) {
+ Log.d(TAG, "disconnect: client=" + record.getClientInfo());
+ }
+ record.disconnect();
+ }
+ });
+ }
+
+ @Override
+ public void pauseStream(final IMediaRouteClientCallback callback) {
+ mHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ ClientRecord record = mClientRecords.get(callback.asBinder());
+ if (record == null) {
+ return; // spurious
+ }
+
+ if (DEBUG) {
+ Log.d(TAG, "pauseStream: client=" + record.getClientInfo());
+ }
+ record.pauseStream();
+ }
+ });
+ }
+
+ @Override
+ public void resumeStream(final IMediaRouteClientCallback callback) {
+ mHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ ClientRecord record = mClientRecords.get(callback.asBinder());
+ if (record == null) {
+ return; // spurious
+ }
+
+ if (DEBUG) {
+ Log.d(TAG, "resumeStream: client=" + record.getClientInfo());
+ }
+ record.resumeStream();
+ }
+ });
+ }
+ }
+
+ // Must be accessed on handler
+ private final class ClientRecord implements IBinder.DeathRecipient {
+ private final IMediaRouteClientCallback mClientCallback;
+ private final ClientInfo mClient;
+ private final ClientSession mSession;
+
+ private int mDiscoverySeq;
+ private DiscoveryRequest mDiscoveryRequest;
+ private DiscoveryCallback mDiscoveryCallback;
+ private final ArrayMap<String, DestinationRecord> mDestinations =
+ new ArrayMap<String, DestinationRecord>();
+
+ private int mConnectionSeq;
+ private ConnectionRequest mConnectionRequest;
+ private ConnectionCallback mConnectionCallback;
+ private ConnectionInfo mConnection;
+ private boolean mConnectionPaused;
+
+ public ClientRecord(IMediaRouteClientCallback callback,
+ ClientInfo client, ClientSession session) {
+ mClientCallback = callback;
+ mClient = client;
+ mSession = session;
+ }
+
+ // Invoked on binder thread unlike all other methods in this class.
+ @Override
+ public void binderDied() {
+ mService.unregisterClient(mClientCallback, true);
+ }
+
+ public ClientInfo getClientInfo() {
+ return mClient;
+ }
+
+ public void release() {
+ stopDiscovery();
+ disconnect();
+ }
+
+ public void startDiscovery(int seq, List<MediaRouteSelector> selectors,
+ int flags) {
+ stopDiscovery();
+
+ mDiscoverySeq = seq;
+ mDiscoveryRequest = new DiscoveryRequest(selectors);
+ mDiscoveryRequest.setFlags(flags);
+ mDiscoveryCallback = new DiscoveryCallback(this);
+ boolean started = mSession.onStartDiscovery(mDiscoveryRequest, mDiscoveryCallback);
+ if (!started) {
+ dispatchDiscoveryFailed(mDiscoveryCallback,
+ MediaRouter.DISCOVERY_ERROR_ABORTED, null, null);
+ clearDiscovery();
+ }
+ }
+
+ public void stopDiscovery() {
+ if (mDiscoveryRequest != null) {
+ mSession.onStopDiscovery();
+ clearDiscovery();
+ }
+ }
+
+ private void clearDiscovery() {
+ mDestinations.clear();
+ mDiscoveryRequest = null;
+ mDiscoveryCallback = null;
+ }
+
+ public void connect(int seq, String destinationId, String routeId,
+ int flags, Bundle extras) {
+ disconnect();
+
+ mConnectionSeq = seq;
+ mConnectionCallback = new ConnectionCallback(this);
+
+ DestinationRecord destinationRecord = mDestinations.get(destinationId);
+ if (destinationRecord == null) {
+ Log.w(TAG, "Aborting connection to route since no matching destination "
+ + "was found in the list of known destinations: "
+ + "destinationId=" + destinationId);
+ dispatchConnectionFailed(mConnectionCallback,
+ MediaRouter.CONNECTION_ERROR_ABORTED, null, null);
+ clearConnection();
+ return;
+ }
+
+ RouteInfo route = destinationRecord.getRoute(routeId);
+ if (route == null) {
+ Log.w(TAG, "Aborting connection to route since no matching route "
+ + "was found in the list of known routes: "
+ + "destination=" + destinationRecord.destination
+ + ", routeId=" + routeId);
+ dispatchConnectionFailed(mConnectionCallback,
+ MediaRouter.CONNECTION_ERROR_ABORTED, null, null);
+ clearConnection();
+ return;
+ }
+
+ mConnectionRequest = new ConnectionRequest(route);
+ mConnectionRequest.setFlags(flags);
+ mConnectionRequest.setExtras(extras);
+ boolean started = mSession.onConnect(mConnectionRequest, mConnectionCallback);
+ if (!started) {
+ dispatchConnectionFailed(mConnectionCallback,
+ MediaRouter.CONNECTION_ERROR_ABORTED, null, null);
+ clearConnection();
+ }
+ }
+
+ public void disconnect() {
+ if (mConnectionRequest != null) {
+ mSession.onDisconnect();
+ clearConnection();
+ }
+ }
+
+ private void clearConnection() {
+ mConnectionRequest = null;
+ mConnectionCallback = null;
+ if (mConnection != null) {
+ mConnection.close();
+ mConnection = null;
+ }
+ mConnectionPaused = false;
+ }
+
+ public void pauseStream() {
+ if (mConnectionRequest != null && !mConnectionPaused) {
+ mConnectionPaused = true;
+ mSession.onPauseStream();
+ }
+ }
+
+ public void resumeStream() {
+ if (mConnectionRequest != null && mConnectionPaused) {
+ mConnectionPaused = false;
+ mSession.onResumeStream();
+ }
+ }
+
+ public void dispatchDestinationFound(DiscoveryCallback callback,
+ DestinationInfo destination, List<RouteInfo> routes) {
+ if (callback == mDiscoveryCallback) {
+ if (DEBUG) {
+ Log.d(TAG, "destinationFound: destination=" + destination
+ + ", routes=" + routes);
+ }
+ mDestinations.put(destination.getId(),
+ new DestinationRecord(destination, routes));
+
+ ParcelableDestinationInfo pdi = new ParcelableDestinationInfo();
+ pdi.id = destination.getId();
+ pdi.name = destination.getName();
+ pdi.description = destination.getDescription();
+ pdi.iconResourceId = destination.getIconResourceId();
+ pdi.extras = destination.getExtras();
+ ArrayList<ParcelableRouteInfo> pris = new ArrayList<ParcelableRouteInfo>();
+ for (RouteInfo route : routes) {
+ int selectorIndex = mDiscoveryRequest.getSelectors().indexOf(
+ route.getSelector());
+ if (selectorIndex < 0) {
+ Log.w(TAG, "Ignoring route because the selector does not match "
+ + "any of those that were originally supplied by the "
+ + "client's discovery request: destination=" + destination
+ + ", route=" + route);
+ continue;
+ }
+
+ ParcelableRouteInfo pri = new ParcelableRouteInfo();
+ pri.id = route.getId();
+ pri.selectorIndex = selectorIndex;
+ pri.features = route.getFeatures();
+ pri.protocols = route.getProtocols().toArray(
+ new String[route.getProtocols().size()]);
+ pri.extras = route.getExtras();
+ pris.add(pri);
+ }
+ try {
+ mClientCallback.onDestinationFound(mDiscoverySeq, pdi,
+ pris.toArray(new ParcelableRouteInfo[pris.size()]));
+ } catch (RemoteException ex) {
+ // binder death handled elsewhere
+ }
+ }
+ }
+
+ public void dispatchDestinationLost(DiscoveryCallback callback,
+ DestinationInfo destination) {
+ if (callback == mDiscoveryCallback) {
+ if (DEBUG) {
+ Log.d(TAG, "destinationLost: destination=" + destination);
+ }
+
+ if (mDestinations.get(destination.getId()).destination == destination) {
+ mDestinations.remove(destination.getId());
+ try {
+ mClientCallback.onDestinationLost(mDiscoverySeq, destination.getId());
+ } catch (RemoteException ex) {
+ // binder death handled elsewhere
+ }
+ }
+ }
+ }
+
+ public void dispatchDiscoveryFailed(DiscoveryCallback callback,
+ int error, CharSequence message, Bundle extras) {
+ if (callback == mDiscoveryCallback) {
+ if (DEBUG) {
+ Log.d(TAG, "discoveryFailed: error=" + error + ", message=" + message
+ + ", extras=" + extras);
+ }
+
+ try {
+ mClientCallback.onDiscoveryFailed(mDiscoverySeq, error, message, extras);
+ } catch (RemoteException ex) {
+ // binder death handled elsewhere
+ }
+ }
+ }
+
+ public void dispatchConnected(ConnectionCallback callback, ConnectionInfo connection) {
+ if (callback == mConnectionCallback) {
+ if (DEBUG) {
+ Log.d(TAG, "connected: connection=" + connection);
+ }
+ if (mConnection == null) {
+ mConnection = connection;
+
+ ParcelableConnectionInfo pci = new ParcelableConnectionInfo();
+ pci.audioAttributes = connection.getAudioAttributes();
+ pci.presentationDisplayId = connection.getPresentationDisplay() != null ?
+ connection.getPresentationDisplay().getDisplayId() : -1;
+ pci.protocolBinders = new IBinder[connection.getProtocols().size()];
+ for (int i = 0; i < pci.protocolBinders.length; i++) {
+ pci.protocolBinders[i] = connection.getProtocolBinder(i);
+ }
+ pci.extras = connection.getExtras();
+ try {
+ mClientCallback.onConnected(mConnectionSeq, pci);
+ } catch (RemoteException ex) {
+ // binder death handled elsewhere
+ }
+ } else {
+ Log.w(TAG, "Media route service called onConnected() while already "
+ + "connected.");
+ }
+ }
+ }
+
+ public void dispatchDisconnected(ConnectionCallback callback) {
+ if (callback == mConnectionCallback) {
+ if (DEBUG) {
+ Log.d(TAG, "disconnected");
+ }
+
+ if (mConnection != null) {
+ mConnection.close();
+ mConnection = null;
+
+ try {
+ mClientCallback.onDisconnected(mConnectionSeq);
+ } catch (RemoteException ex) {
+ // binder death handled elsewhere
+ }
+ }
+ }
+ }
+
+ public void dispatchConnectionFailed(ConnectionCallback callback,
+ int error, CharSequence message, Bundle extras) {
+ if (callback == mConnectionCallback) {
+ if (DEBUG) {
+ Log.d(TAG, "connectionFailed: error=" + error + ", message=" + message
+ + ", extras=" + extras);
+ }
+
+ try {
+ mClientCallback.onConnectionFailed(mConnectionSeq, error, message, extras);
+ } catch (RemoteException ex) {
+ // binder death handled elsewhere
+ }
+ }
+ }
+ }
+
+ private static final class DestinationRecord {
+ public final DestinationInfo destination;
+ public final List<RouteInfo> routes;
+
+ public DestinationRecord(DestinationInfo destination, List<RouteInfo> routes) {
+ this.destination = destination;
+ this.routes = routes;
+ }
+
+ public RouteInfo getRoute(String routeId) {
+ final int count = routes.size();
+ for (int i = 0; i < count; i++) {
+ RouteInfo route = routes.get(i);
+ if (route.getId().equals(routeId)) {
+ return route;
+ }
+ }
+ return null;
+ }
+ }
+}
diff --git a/media/java/android/media/routing/MediaRouter.java b/media/java/android/media/routing/MediaRouter.java
new file mode 100644
index 0000000..4f6d324
--- /dev/null
+++ b/media/java/android/media/routing/MediaRouter.java
@@ -0,0 +1,1886 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.media.routing;
+
+import android.annotation.DrawableRes;
+import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.app.Presentation;
+import android.app.Service;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.pm.PackageManager;
+import android.content.pm.PackageManager.NameNotFoundException;
+import android.content.pm.ServiceInfo;
+import android.graphics.drawable.Drawable;
+import android.hardware.display.DisplayManager;
+import android.media.AudioAttributes;
+import android.media.AudioManager;
+import android.media.AudioTrack;
+import android.media.VolumeProvider;
+import android.media.session.MediaController;
+import android.media.session.MediaSession;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.IInterface;
+import android.text.TextUtils;
+import android.util.ArrayMap;
+import android.view.Display;
+
+import java.io.Closeable;
+import java.io.IOException;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Media router allows applications to discover, connect to, control,
+ * and send content to nearby media devices known as destinations.
+ * <p>
+ * There are generally two participants involved in media routing: an
+ * application that wants to send media content to a destination and a
+ * {@link MediaRouteService media route service} that provides the
+ * service of transporting that content where it needs to go on behalf of the
+ * application.
+ * </p><p>
+ * To send media content to a destination, the application must ask the system
+ * to discover available routes to destinations that provide certain capabilities,
+ * establish a connection to a route, then send messages through the connection to
+ * control the routing of audio and video streams, launch remote applications,
+ * and invoke other functions of the destination.
+ * </p><p>
+ * Media router objects are thread-safe.
+ * </p>
+ *
+ * <h3>Destinations</h3>
+ * <p>
+ * The media devices to which an application may send media content are referred
+ * to in the API as destinations. Each destination therefore represents a single
+ * independent device such as a speaker or TV set. Destinations are given meaningful
+ * names and descriptions to help the user associate them with devices in their
+ * environment.
+ * </p><p>
+ * Destinations may be local or remote and may be accessed through various means,
+ * often wirelessly. The user may install media route services to enable
+ * media applications to connect to a variety of destinations with different
+ * capabilities.
+ * </p>
+ *
+ * <h3>Routes</h3>
+ * <p>
+ * Routes represent possible usages or means of reaching and interacting with
+ * a destination. Since destinations may support many different features, they may
+ * each offer multiple routes for applications to choose from based on their needs.
+ * For example, one route might express the ability to stream locally rendered audio
+ * and video to the device; another route might express the ability to send a URL for
+ * the destination to download from the network and play all by itself.
+ * </p><p>
+ * Routes are discovered according to the set of capabilities that
+ * an application or the system is seeking to use at a particular time. For example,
+ * if an application wants to stream music to a destination then it will ask the
+ * {@link MediaRouter} to find routes to destinations can stream music and ignore
+ * all other destinations that cannot.
+ * </p><p>
+ * In general, the application will inspect the set of routes that have been
+ * offered then connect to the most appropriate route for its desired purpose.
+ * </p>
+ *
+ * <h3>Route Selection</h3>
+ * <p>
+ * When the user open the media route chooser activity, the system will display
+ * a list of nearby media destinations which have been discovered. After the
+ * choice is made the application may connect to one of the routes offered by
+ * this destination and begin communicating with the destination.
+ * </p><p>
+ * Destinations are located through a process called discovery. During discovery,
+ * the system will start installed {@link MediaRouteService media route services}
+ * to scan the network for nearby devices that offer the kinds of capabilities that the
+ * application is seeking to use. The application specifies the capabilities it requires by
+ * adding {@link MediaRouteSelector media route selectors} to the media router
+ * using the {@link #addSelector} method. Only destinations that provide routes
+ * which satisfy at least one of these media route selectors will be discovered.
+ * </p><p>
+ * Once the user has selected a destination, the application will be given a chance
+ * to choose one of the routes to which it would like to connect. The application
+ * may switch to a different route from the same destination at a later time but
+ * in order to connect to a new destination, the application must once again launch
+ * the media route chooser activity to ask the user to choose a destination.
+ * </p>
+ *
+ * <h3>Route Protocols</h3>
+ * <p>
+ * Route protocols express capabilities offered by routes. Each media route selector
+ * must specify at least one required protocol by which the routes will be selected.
+ * </p><p>
+ * The framework provides several predefined <code>MediaRouteProtocols</code> which are
+ * defined in the <code>android-support-media-protocols.jar</code> support library.
+ * Applications must statically link this library to make use of these protocols.
+ * </p><p>
+ * The static library approach is used to enable ongoing extension and refinement
+ * of protocols in the SDK and interoperability with the media router implementation
+ * for older platform versions which is offered by the framework support library.
+ * </p><p>
+ * Media route services may also define custom media route protocols of their own
+ * to enable applications to access specialized capabilities of certain destinations
+ * assuming they have linked in the required protocol code.
+ * </p><p>
+ * Refer to <code>android.support.media.protocols.MediaRouteProtocol</code> for more information.
+ * </p>
+ *
+ * <h3>Connections</h3>
+ * <p>
+ * After connecting to a media route, the application can send commands to
+ * the route using any of the protocols that it requested. If the route supports live
+ * audio or video streaming then the application can create an {@link AudioTrack} or
+ * {@link Presentation} to route locally generated content to the destination.
+ * </p>
+ *
+ * <h3>Delegation</h3>
+ * <p>
+ * The creator of the media router is responsible for establishing the policy for
+ * discovering and connecting to destinations. UI components may observe the state
+ * of the media router by {@link #createDelegate creating} a {@link Delegate}.
+ * </p><p>
+ * The media router should also be attached to the {@link MediaSession media session}
+ * that is handling media playback lifecycle. This will allow
+ * authorized {@link MediaController media controllers}, possibly running in other
+ * processes, to provide UI to examine and change the media destination by
+ * {@link MediaController#createMediaRouterDelegate creating} a {@link Delegate}
+ * for the media router associated with the session.
+ * </p>
+ */
+public final class MediaRouter {
+ private final DisplayManager mDisplayManager;
+
+ private final Object mLock = new Object();
+
+ private RoutingCallback mRoutingCallback;
+ private Handler mRoutingCallbackHandler;
+
+ private boolean mReleased;
+ private int mDiscoveryState;
+ private int mConnectionState;
+ private final ArrayList<MediaRouteSelector> mSelectors =
+ new ArrayList<MediaRouteSelector>();
+ private final ArrayMap<DestinationInfo, List<RouteInfo>> mDiscoveredDestinations =
+ new ArrayMap<DestinationInfo, List<RouteInfo>>();
+ private RouteInfo mSelectedRoute;
+ private ConnectionInfo mConnection;
+
+ /** @hide */
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef(value = { DISCOVERY_STATE_STOPPED, DISCOVERY_STATE_STARTED })
+ public @interface DiscoveryState { }
+
+ /**
+ * Discovery state: Discovery is not currently in progress.
+ */
+ public static final int DISCOVERY_STATE_STOPPED = 0;
+
+ /**
+ * Discovery state: Discovery is being performed.
+ */
+ public static final int DISCOVERY_STATE_STARTED = 1;
+
+ /** @hide */
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef(flag = true, value = { DISCOVERY_FLAG_BACKGROUND })
+ public @interface DiscoveryFlags { }
+
+ /**
+ * Discovery flag: Indicates that the client has requested passive discovery in
+ * the background. The media route service should try to use less power and rely
+ * more on its internal caches to minimize its impact.
+ */
+ public static final int DISCOVERY_FLAG_BACKGROUND = 1 << 0;
+
+ /** @hide */
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef(value = { DISCOVERY_ERROR_UNKNOWN, DISCOVERY_ERROR_ABORTED,
+ DISCOVERY_ERROR_NO_CONNECTIVITY })
+ public @interface DiscoveryError { }
+
+ /**
+ * Discovery error: Unknown error; refer to the error message for details.
+ */
+ public static final int DISCOVERY_ERROR_UNKNOWN = 0;
+
+ /**
+ * Discovery error: The media router or media route service has decided not to
+ * handle the discovery request for some reason.
+ */
+ public static final int DISCOVERY_ERROR_ABORTED = 1;
+
+ /**
+ * Discovery error: The media route service is unable to perform discovery
+ * due to a lack of connectivity such as because the radio is disabled.
+ */
+ public static final int DISCOVERY_ERROR_NO_CONNECTIVITY = 2;
+
+ /** @hide */
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef(value = { CONNECTION_STATE_DISCONNECTED, CONNECTION_STATE_CONNECTING,
+ CONNECTION_STATE_CONNECTED })
+ public @interface ConnectionState { }
+
+ /**
+ * Connection state: No destination has been selected. Media content should
+ * be sent to the default output.
+ */
+ public static final int CONNECTION_STATE_DISCONNECTED = 0;
+
+ /**
+ * Connection state: The application is in the process of connecting to
+ * a route offered by the selected destination.
+ */
+ public static final int CONNECTION_STATE_CONNECTING = 1;
+
+ /**
+ * Connection state: The application has connected to a route offered by
+ * the selected destination.
+ */
+ public static final int CONNECTION_STATE_CONNECTED = 2;
+
+ /** @hide */
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef(flag = true, value = { CONNECTION_FLAG_BARGE })
+ public @interface ConnectionFlags { }
+
+ /**
+ * Connection flag: Indicates that the client has requested to barge in and evict
+ * other clients that might have already connected to the destination and that
+ * would otherwise prevent this client from connecting. When this flag is not
+ * set, the media route service should be polite and report
+ * {@link MediaRouter#CONNECTION_ERROR_BUSY} in case the destination is
+ * already occupied and cannot accept additional connections.
+ */
+ public static final int CONNECTION_FLAG_BARGE = 1 << 0;
+
+ /** @hide */
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef(value = { CONNECTION_ERROR_UNKNOWN, CONNECTION_ERROR_ABORTED,
+ CONNECTION_ERROR_UNAUTHORIZED, CONNECTION_ERROR_UNAUTHORIZED,
+ CONNECTION_ERROR_BUSY, CONNECTION_ERROR_TIMEOUT, CONNECTION_ERROR_BROKEN })
+ public @interface ConnectionError { }
+
+ /**
+ * Connection error: Unknown error; refer to the error message for details.
+ */
+ public static final int CONNECTION_ERROR_UNKNOWN = 0;
+
+ /**
+ * Connection error: The media router or media route service has decided not to
+ * handle the connection request for some reason.
+ */
+ public static final int CONNECTION_ERROR_ABORTED = 1;
+
+ /**
+ * Connection error: The device has refused the connection from this client.
+ * This error should be avoided because the media route service should attempt
+ * to filter out devices that the client cannot access as it performs discovery
+ * on behalf of that client.
+ */
+ public static final int CONNECTION_ERROR_UNAUTHORIZED = 2;
+
+ /**
+ * Connection error: The device is unreachable over the network.
+ */
+ public static final int CONNECTION_ERROR_UNREACHABLE = 3;
+
+ /**
+ * Connection error: The device is already busy serving another client and
+ * the connection request did not ask to barge in.
+ */
+ public static final int CONNECTION_ERROR_BUSY = 4;
+
+ /**
+ * Connection error: A timeout occurred during connection.
+ */
+ public static final int CONNECTION_ERROR_TIMEOUT = 5;
+
+ /**
+ * Connection error: The connection to the device was severed unexpectedly.
+ */
+ public static final int CONNECTION_ERROR_BROKEN = 6;
+
+ /**
+ * Connection error: The connection was terminated because a different client barged
+ * in and took control of the destination.
+ */
+ public static final int CONNECTION_ERROR_BARGED = 7;
+
+ /** @hide */
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef(value = { DISCONNECTION_REASON_APPLICATION_REQUEST,
+ DISCONNECTION_REASON_USER_REQUEST, DISCONNECTION_REASON_ERROR })
+ public @interface DisconnectionReason { }
+
+ /**
+ * Disconnection reason: The application requested disconnection itself.
+ */
+ public static final int DISCONNECTION_REASON_APPLICATION_REQUEST = 0;
+
+ /**
+ * Disconnection reason: The user requested disconnection.
+ */
+ public static final int DISCONNECTION_REASON_USER_REQUEST = 1;
+
+ /**
+ * Disconnection reason: An error occurred.
+ */
+ public static final int DISCONNECTION_REASON_ERROR = 2;
+
+ /** @hide */
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef(flag = true, value = { ROUTE_FEATURE_LIVE_AUDIO, ROUTE_FEATURE_LIVE_VIDEO })
+ public @interface RouteFeatures { }
+
+ /**
+ * Route feature: Live audio.
+ * <p>
+ * A route that supports live audio streams audio rendered by the application
+ * to the destination.
+ * </p><p>
+ * To take advantage of live audio routing, the application must render its
+ * media using the audio attributes specified by {@link #getPreferredAudioAttributes}.
+ * </p>
+ *
+ * @see #getPreferredAudioAttributes
+ * @see android.media.AudioAttributes
+ */
+ public static final int ROUTE_FEATURE_LIVE_AUDIO = 1 << 0;
+
+ /**
+ * Route feature: Live video.
+ * <p>
+ * A route that supports live video streams video rendered by the application
+ * to the destination.
+ * </p><p>
+ * To take advantage of live video routing, the application must render its
+ * media to a {@link android.app.Presentation presentation window} on the
+ * display specified by {@link #getPreferredPresentationDisplay}.
+ * </p>
+ *
+ * @see #getPreferredPresentationDisplay
+ * @see android.app.Presentation
+ */
+ public static final int ROUTE_FEATURE_LIVE_VIDEO = 1 << 1;
+
+ /**
+ * Creates a media router.
+ *
+ * @param context The context with which the router is associated.
+ */
+ public MediaRouter(@NonNull Context context) {
+ if (context == null) {
+ throw new IllegalArgumentException("context must not be null");
+ }
+
+ mDisplayManager = (DisplayManager)context.getSystemService(Context.DISPLAY_SERVICE);
+ }
+
+ /** @hide */
+ public IMediaRouter getBinder() {
+ // todo
+ return null;
+ }
+
+ /**
+ * Disconnects from the selected destination and releases the media router.
+ * <p>
+ * This method should be called by the application when it no longer requires
+ * the media router to ensure that all bound resources may be cleaned up.
+ * </p>
+ */
+ public void release() {
+ synchronized (mLock) {
+ mReleased = true;
+ // todo
+ }
+ }
+
+ /**
+ * Returns true if the media router has been released.
+ */
+ public boolean isReleased() {
+ synchronized (mLock) {
+ return mReleased;
+ }
+ }
+
+ /**
+ * Gets the current route discovery state.
+ *
+ * @return The current discovery state: one of {@link #DISCOVERY_STATE_STOPPED},
+ * {@link #DISCOVERY_STATE_STARTED}.
+ */
+ public @DiscoveryState int getDiscoveryState() {
+ synchronized (mLock) {
+ return mDiscoveryState;
+ }
+ }
+
+ /**
+ * Gets the current route connection state.
+ *
+ * @return The current state: one of {@link #CONNECTION_STATE_DISCONNECTED},
+ * {@link #CONNECTION_STATE_CONNECTING} or {@link #CONNECTION_STATE_CONNECTED}.
+ */
+ public @ConnectionState int getConnectionState() {
+ synchronized (mLock) {
+ return mConnectionState;
+ }
+ }
+
+ /**
+ * Creates a media router delegate through which the destination of the media
+ * router may be controlled.
+ * <p>
+ * This is the point of entry for UI code that initiates discovery and
+ * connection to routes.
+ * </p>
+ */
+ public @NonNull Delegate createDelegate() {
+ return null; // todo
+ }
+
+ /**
+ * Sets a callback to participate in route discovery, filtering, and connection
+ * establishment.
+ *
+ * @param callback The callback to set, or null if none.
+ * @param handler The handler to receive callbacks, or null to use the current thread.
+ */
+ public void setRoutingCallback(@Nullable RoutingCallback callback,
+ @Nullable Handler handler) {
+ synchronized (mLock) {
+ if (callback == null) {
+ mRoutingCallback = null;
+ mRoutingCallbackHandler = null;
+ } else {
+ mRoutingCallback = callback;
+ mRoutingCallbackHandler = handler != null ? handler : new Handler();
+ }
+ }
+ }
+
+ /**
+ * Adds a media route selector to use to find destinations that have
+ * routes with the specified capabilities during route discovery.
+ */
+ public void addSelector(@NonNull MediaRouteSelector selector) {
+ if (selector == null) {
+ throw new IllegalArgumentException("selector must not be null");
+ }
+
+ synchronized (mLock) {
+ if (!mSelectors.contains(selector)) {
+ mSelectors.add(selector);
+ // todo
+ }
+ }
+ }
+
+ /**
+ * Removes a media route selector.
+ */
+ public void removeSelector(@NonNull MediaRouteSelector selector) {
+ if (selector == null) {
+ throw new IllegalArgumentException("selector must not be null");
+ }
+
+ synchronized (mLock) {
+ if (mSelectors.remove(selector)) {
+ // todo
+ }
+ }
+ }
+
+ /**
+ * Removes all media route selectors.
+ * <p>
+ * Note that at least one selector must be added in order to perform discovery.
+ * </p>
+ */
+ public void clearSelectors() {
+ synchronized (mLock) {
+ if (!mSelectors.isEmpty()) {
+ mSelectors.clear();
+ // todo
+ }
+ }
+ }
+
+ /**
+ * Gets a list of all media route selectors to consider during discovery.
+ */
+ public @NonNull List<MediaRouteSelector> getSelectors() {
+ synchronized (mLock) {
+ return new ArrayList<MediaRouteSelector>(mSelectors);
+ }
+ }
+
+ /**
+ * Gets the connection to the currently selected route.
+ *
+ * @return The connection to the currently selected route, or null if not connected.
+ */
+ public @NonNull ConnectionInfo getConnection() {
+ synchronized (mLock) {
+ return mConnection;
+ }
+ }
+
+ /**
+ * Gets the list of discovered destinations.
+ * <p>
+ * This list is only valid while discovery is running and is null otherwise.
+ * </p>
+ *
+ * @return The list of discovered destinations, or null if discovery is not running.
+ */
+ public @NonNull List<DestinationInfo> getDiscoveredDestinations() {
+ synchronized (mLock) {
+ if (mDiscoveryState == DISCOVERY_STATE_STARTED) {
+ return new ArrayList<DestinationInfo>(mDiscoveredDestinations.keySet());
+ }
+ return null;
+ }
+ }
+
+ /**
+ * Gets the list of discovered routes for a particular destination.
+ * <p>
+ * This list is only valid while discovery is running and is null otherwise.
+ * </p>
+ *
+ * @param destination The destination for which to get the list of discovered routes.
+ * @return The list of discovered routes for the destination, or null if discovery
+ * is not running.
+ */
+ public @NonNull List<RouteInfo> getDiscoveredRoutes(@NonNull DestinationInfo destination) {
+ if (destination == null) {
+ throw new IllegalArgumentException("destination must not be null");
+ }
+ synchronized (mLock) {
+ if (mDiscoveryState == DISCOVERY_STATE_STARTED) {
+ List<RouteInfo> routes = mDiscoveredDestinations.get(destination);
+ if (routes != null) {
+ return new ArrayList<RouteInfo>(routes);
+ }
+ }
+ return null;
+ }
+ }
+
+ /**
+ * Gets the destination that has been selected.
+ *
+ * @return The selected destination, or null if disconnected.
+ */
+ public @Nullable DestinationInfo getSelectedDestination() {
+ synchronized (mLock) {
+ return mSelectedRoute != null ? mSelectedRoute.getDestination() : null;
+ }
+ }
+
+ /**
+ * Gets the route that has been selected.
+ *
+ * @return The selected destination, or null if disconnected.
+ */
+ public @Nullable RouteInfo getSelectedRoute() {
+ synchronized (mLock) {
+ return mSelectedRoute;
+ }
+ }
+
+ /**
+ * Gets the preferred audio attributes that should be used to stream live audio content
+ * based on the connected route.
+ * <p>
+ * Use an {@link AudioTrack} to send audio content to the destination with these
+ * audio attributes.
+ * </p><p>
+ * The preferred audio attributes may change when a connection is established but it
+ * will remain constant until disconnected.
+ * </p>
+ *
+ * @return The preferred audio attributes to use. When connected, returns the
+ * route's audio attributes or null if it does not support live audio streaming.
+ * Otherwise returns audio attributes associated with {@link AudioAttributes#USAGE_MEDIA}.
+ */
+ public @Nullable AudioAttributes getPreferredAudioAttributes() {
+ synchronized (mLock) {
+ if (mConnection != null) {
+ return mConnection.getAudioAttributes();
+ }
+ return new AudioAttributes.Builder()
+ .setLegacyStreamType(AudioManager.STREAM_MUSIC)
+ .build();
+ }
+ }
+
+ /**
+ * Gets the preferred presentation display that should be used to stream live video content
+ * based on the connected route.
+ * <p>
+ * Use a {@link Presentation} to send video content to the destination with this display.
+ * </p><p>
+ * The preferred presentation display may change when a connection is established but it
+ * will remain constant until disconnected.
+ * </p>
+ *
+ * @return The preferred presentation display to use. When connected, returns
+ * the route's presentation display or null if it does not support live video
+ * streaming. Otherwise returns the first available
+ * {@link DisplayManager#DISPLAY_CATEGORY_PRESENTATION presentation display},
+ * such as a mirrored wireless or HDMI display or null if none.
+ */
+ public @Nullable Display getPreferredPresentationDisplay() {
+ synchronized (mLock) {
+ if (mConnection != null) {
+ return mConnection.getPresentationDisplay();
+ }
+ Display[] displays = mDisplayManager.getDisplays(
+ DisplayManager.DISPLAY_CATEGORY_PRESENTATION);
+ return displays.length != 0 ? displays[0] : null;
+ }
+ }
+
+ /**
+ * Gets the preferred volume provider that should be used to control the volume
+ * of content rendered on the currently selected route.
+ * <p>
+ * The preferred volume provider may change when a connection is established but it
+ * will remain the same until disconnected.
+ * </p>
+ *
+ * @return The preferred volume provider to use, or null if the currently
+ * selected route does not support remote volume adjustment or if the connection
+ * is not yet established. If no route is selected, returns null to indicate
+ * that system volume control should be used.
+ */
+ public @Nullable VolumeProvider getPreferredVolumeProvider() {
+ synchronized (mLock) {
+ if (mConnection != null) {
+ return mConnection.getVolumeProvider();
+ }
+ return null;
+ }
+ }
+
+ /**
+ * Requests to pause streaming of live audio or video routes.
+ * Should be called when the application is going into the background and is
+ * no longer rendering content locally.
+ * <p>
+ * This method does nothing unless a connection has been established.
+ * </p>
+ */
+ public void pauseStream() {
+ // todo
+ }
+
+ /**
+ * Requests to resume streaming of live audio or video routes.
+ * May be called when the application is returning to the foreground and is
+ * about to resume rendering content locally.
+ * <p>
+ * This method does nothing unless a connection has been established.
+ * </p>
+ */
+ public void resumeStream() {
+ // todo
+ }
+
+ /**
+ * This class is used by UI components to let the user discover and
+ * select a destination to which the media router should connect.
+ * <p>
+ * This API has somewhat more limited functionality than the {@link MediaRouter}
+ * itself because it is designed to allow applications to control
+ * the destination of media router instances that belong to other processes.
+ * </p><p>
+ * To control the destination of your own media router, call
+ * {@link #createDelegate} to obtain a local delegate object.
+ * </p><p>
+ * To control the destination of a media router that belongs to another process,
+ * first obtain a {@link MediaController} that is associated with the media playback
+ * that is occurring in that process, then call
+ * {@link MediaController#createMediaRouterDelegate} to obtain an instance of
+ * its destination controls. Note that special permissions may be required to
+ * obtain the {@link MediaController} instance in the first place.
+ * </p>
+ */
+ public static final class Delegate {
+ /**
+ * Returns true if the media router has been released.
+ */
+ public boolean isReleased() {
+ // todo
+ return false;
+ }
+
+ /**
+ * Gets the current route discovery state.
+ *
+ * @return The current discovery state: one of {@link #DISCOVERY_STATE_STOPPED},
+ * {@link #DISCOVERY_STATE_STARTED}.
+ */
+ public @DiscoveryState int getDiscoveryState() {
+ // todo
+ return -1;
+ }
+
+ /**
+ * Gets the current route connection state.
+ *
+ * @return The current state: one of {@link #CONNECTION_STATE_DISCONNECTED},
+ * {@link #CONNECTION_STATE_CONNECTING} or {@link #CONNECTION_STATE_CONNECTED}.
+ */
+ public @ConnectionState int getConnectionState() {
+ // todo
+ return -1;
+ }
+
+ /**
+ * Gets the currently selected destination.
+ *
+ * @return The destination information, or null if none.
+ */
+ public @Nullable DestinationInfo getSelectedDestination() {
+ return null;
+ }
+
+ /**
+ * Gets the list of discovered destinations.
+ * <p>
+ * This list is only valid while discovery is running and is null otherwise.
+ * </p>
+ *
+ * @return The list of discovered destinations, or null if discovery is not running.
+ */
+ public @NonNull List<DestinationInfo> getDiscoveredDestinations() {
+ return null;
+ }
+
+ /**
+ * Adds a callback to receive state changes.
+ *
+ * @param callback The callback to set, or null if none.
+ * @param handler The handler to receive callbacks, or null to use the current thread.
+ */
+ public void addStateCallback(@Nullable StateCallback callback,
+ @Nullable Handler handler) {
+ if (callback == null) {
+ throw new IllegalArgumentException("callback must not be null");
+ }
+ if (handler == null) {
+ handler = new Handler();
+ }
+ // todo
+ }
+
+ /**
+ * Removes a callback for state changes.
+ *
+ * @param callback The callback to set, or null if none.
+ */
+ public void removeStateCallback(@Nullable StateCallback callback) {
+ // todo
+ }
+
+ /**
+ * Starts performing discovery.
+ * <p>
+ * Performing discovery is expensive. Make sure to call {@link #stopDiscovery}
+ * as soon as possible once a new destination has been selected to allow the system
+ * to stop services associated with discovery.
+ * </p>
+ *
+ * @param flags The discovery flags, such as {@link MediaRouter#DISCOVERY_FLAG_BACKGROUND}.
+ */
+ public void startDiscovery(@DiscoveryFlags int flags) {
+ // todo
+ }
+
+ /**
+ * Stops performing discovery.
+ */
+ public void stopDiscovery() {
+ // todo
+ }
+
+ /**
+ * Connects to a destination during route discovery.
+ * <p>
+ * This method may only be called while route discovery is active and the
+ * destination appears in the
+ * {@link #getDiscoveredDestinations list of discovered destinations}.
+ * If the media router is already connected to a route then it will first disconnect
+ * from the current route then connect to the new route.
+ * </p>
+ *
+ * @param destination The destination to which the media router should connect.
+ * @param flags The connection flags, such as {@link MediaRouter#CONNECTION_FLAG_BARGE}.
+ */
+ public void connect(@NonNull DestinationInfo destination, @DiscoveryFlags int flags) {
+ // todo
+ }
+
+ /**
+ * Disconnects from the currently selected destination.
+ * <p>
+ * Does nothing if not currently connected.
+ * </p>
+ *
+ * @param reason The reason for the disconnection: one of
+ * {@link #DISCONNECTION_REASON_APPLICATION_REQUEST},
+ * {@link #DISCONNECTION_REASON_USER_REQUEST}, or {@link #DISCONNECTION_REASON_ERROR}.
+ */
+ public void disconnect(@DisconnectionReason int reason) {
+ // todo
+ }
+ }
+
+ /**
+ * Describes immutable properties of a connection to a route.
+ */
+ public static final class ConnectionInfo {
+ private final RouteInfo mRoute;
+ private final AudioAttributes mAudioAttributes;
+ private final Display mPresentationDisplay;
+ private final VolumeProvider mVolumeProvider;
+ private final IBinder[] mProtocolBinders;
+ private final Object[] mProtocolInstances;
+ private final Bundle mExtras;
+ private final ArrayList<Closeable> mCloseables;
+
+ private static final Class<?>[] MEDIA_ROUTE_PROTOCOL_CTOR_PARAMETERS =
+ new Class<?>[] { IBinder.class };
+
+ ConnectionInfo(RouteInfo route,
+ AudioAttributes audioAttributes, Display display,
+ VolumeProvider volumeProvider, IBinder[] protocolBinders,
+ Bundle extras, ArrayList<Closeable> closeables) {
+ mRoute = route;
+ mAudioAttributes = audioAttributes;
+ mPresentationDisplay = display;
+ mVolumeProvider = volumeProvider;
+ mProtocolBinders = protocolBinders;
+ mProtocolInstances = new Object[mProtocolBinders.length];
+ mExtras = extras;
+ mCloseables = closeables;
+ }
+
+ /**
+ * Gets the route that is connected.
+ */
+ public @NonNull RouteInfo getRoute() {
+ return mRoute;
+ }
+
+ /**
+ * Gets the audio attributes which the client should use to stream audio
+ * to the destination, or null if the route does not support live audio streaming.
+ */
+ public @Nullable AudioAttributes getAudioAttributes() {
+ return mAudioAttributes;
+ }
+
+ /**
+ * Gets the display which the client should use to stream video to the
+ * destination using a {@link Presentation}, or null if the route does not
+ * support live video streaming.
+ */
+ public @Nullable Display getPresentationDisplay() {
+ return mPresentationDisplay;
+ }
+
+ /**
+ * Gets the route's volume provider, or null if none.
+ */
+ public @Nullable VolumeProvider getVolumeProvider() {
+ return mVolumeProvider;
+ }
+
+ /**
+ * Gets the set of supported route features.
+ */
+ public @RouteFeatures int getFeatures() {
+ return mRoute.getFeatures();
+ }
+
+ /**
+ * Gets the list of supported route protocols.
+ * <p>
+ * Refer to <code>android.support.media.protocols.MediaRouteProtocol</code>
+ * for more information.
+ * </p>
+ */
+ public @NonNull List<String> getProtocols() {
+ return mRoute.getProtocols();
+ }
+
+ /**
+ * Gets an instance of a route protocol object that wraps the protocol binder
+ * and provides easy access to the protocol's functionality.
+ * <p>
+ * This is a convenience method which invokes {@link #getProtocolBinder(String)}
+ * using the name of the provided class then passes the resulting {@link IBinder}
+ * to a single-argument constructor of that class.
+ * </p><p>
+ * Refer to <code>android.support.media.protocols.MediaRouteProtocol</code>
+ * for more information.
+ * </p>
+ */
+ @SuppressWarnings("unchecked")
+ public @Nullable <T> T getProtocolObject(Class<T> clazz) {
+ int index = getProtocols().indexOf(clazz.getName());
+ if (index < 0) {
+ return null;
+ }
+ if (mProtocolInstances[index] == null && mProtocolBinders[index] != null) {
+ final Constructor<T> ctor;
+ try {
+ ctor = clazz.getConstructor(MEDIA_ROUTE_PROTOCOL_CTOR_PARAMETERS);
+ } catch (NoSuchMethodException ex) {
+ throw new RuntimeException("Could not find public constructor "
+ + "with IBinder argument in protocol class: " + clazz.getName(), ex);
+ }
+ try {
+ mProtocolInstances[index] = ctor.newInstance(mProtocolBinders[index]);
+ } catch (InstantiationException | IllegalAccessException
+ | InvocationTargetException ex) {
+ throw new RuntimeException("Could create instance of protocol class: "
+ + clazz.getName(), ex);
+ }
+ }
+ return (T)mProtocolInstances[index];
+ }
+
+ /**
+ * Gets the {@link IBinder} that provides access to the specified route protocol
+ * or null if the protocol is not supported.
+ * <p>
+ * Refer to <code>android.support.media.protocols.MediaRouteProtocol</code>
+ * for more information.
+ * </p>
+ */
+ public @Nullable IBinder getProtocolBinder(@NonNull String name) {
+ int index = getProtocols().indexOf(name);
+ return index >= 0 ? mProtocolBinders[index] : null;
+ }
+
+ /**
+ * Gets the {@link IBinder} that provides access to the specified route protocol
+ * at the given index in the protocol list or null if the protocol is not supported.
+ * <p>
+ * Refer to <code>android.support.media.protocols.MediaRouteProtocol</code>
+ * for more information.
+ * </p>
+ */
+ public @Nullable IBinder getProtocolBinder(int index) {
+ return mProtocolBinders[index];
+ }
+
+ /**
+ * Gets optional extra media route service or protocol specific information about
+ * the connection. Use the service or protocol name as the prefix for
+ * any extras to avoid namespace collisions.
+ */
+ public @Nullable Bundle getExtras() {
+ return mExtras;
+ }
+
+ /**
+ * Closes all closeables associated with the connection when the connection
+ * is being torn down.
+ */
+ void close() {
+ final int count = mCloseables.size();
+ for (int i = 0; i < count; i++) {
+ try {
+ mCloseables.get(i).close();
+ } catch (IOException ex) {
+ }
+ }
+ }
+
+ @Override
+ public @NonNull String toString() {
+ return "ConnectionInfo{ route=" + mRoute
+ + ", audioAttributes=" + mAudioAttributes
+ + ", presentationDisplay=" + mPresentationDisplay
+ + ", volumeProvider=" + mVolumeProvider
+ + ", protocolBinders=" + mProtocolBinders + " }";
+ }
+
+ /**
+ * Builds {@link ConnectionInfo} objects.
+ */
+ public static final class Builder {
+ private final RouteInfo mRoute;
+ private AudioAttributes mAudioAttributes;
+ private Display mPresentationDisplay;
+ private VolumeProvider mVolumeProvider;
+ private final IBinder[] mProtocols;
+ private Bundle mExtras;
+ private final ArrayList<Closeable> mCloseables = new ArrayList<Closeable>();
+
+ /**
+ * Creates a builder for connection information.
+ *
+ * @param route The route that is connected.
+ */
+ public Builder(@NonNull RouteInfo route) {
+ if (route == null) {
+ throw new IllegalArgumentException("route");
+ }
+ mRoute = route;
+ mProtocols = new IBinder[route.getProtocols().size()];
+ }
+
+ /**
+ * Sets the audio attributes which the client should use to stream audio
+ * to the destination, or null if the route does not support live audio streaming.
+ */
+ public @NonNull Builder setAudioAttributes(
+ @Nullable AudioAttributes audioAttributes) {
+ mAudioAttributes = audioAttributes;
+ return this;
+ }
+
+ /**
+ * Sets the display which the client should use to stream video to the
+ * destination using a {@link Presentation}, or null if the route does not
+ * support live video streaming.
+ */
+ public @NonNull Builder setPresentationDisplay(@Nullable Display display) {
+ mPresentationDisplay = display;
+ return this;
+ }
+
+ /**
+ * Sets the route's volume provider, or null if none.
+ */
+ public @NonNull Builder setVolumeProvider(@Nullable VolumeProvider provider) {
+ mVolumeProvider = provider;
+ return this;
+ }
+
+ /**
+ * Sets the binder stub of a supported route protocol using
+ * the protocol's fully qualified class name. The protocol must be one
+ * of those that was indicated as being supported by the route.
+ * <p>
+ * If the stub implements {@link Closeable} then it will automatically
+ * be closed when the client disconnects from the route.
+ * </p><p>
+ * Refer to <code>android.support.media.protocols.MediaRouteProtocol</code>
+ * for more information.
+ * </p>
+ */
+ public @NonNull Builder setProtocolStub(@NonNull Class<?> clazz,
+ @NonNull IInterface stub) {
+ if (clazz == null) {
+ throw new IllegalArgumentException("clazz must not be null");
+ }
+ if (stub == null) {
+ throw new IllegalArgumentException("stub must not be null");
+ }
+ if (stub instanceof Closeable) {
+ mCloseables.add((Closeable)stub);
+ }
+ return setProtocolBinder(clazz.getName(), stub.asBinder());
+ }
+
+ /**
+ * Sets the binder interface of a supported route protocol by name.
+ * The protocol must be one of those that was indicated as being supported
+ * by the route.
+ * <p>
+ * Refer to <code>android.support.media.protocols.MediaRouteProtocol</code>
+ * for more information.
+ * </p>
+ */
+ public @NonNull Builder setProtocolBinder(@NonNull String name,
+ @NonNull IBinder binder) {
+ if (TextUtils.isEmpty(name)) {
+ throw new IllegalArgumentException("name must not be null or empty");
+ }
+ if (binder == null) {
+ throw new IllegalArgumentException("binder must not be null");
+ }
+ int index = mRoute.getProtocols().indexOf(name);
+ if (index < 0) {
+ throw new IllegalArgumentException("name must specify a protocol that "
+ + "the route actually declared that it supports: "
+ + "name=" + name + ", protocols=" + mRoute.getProtocols());
+ }
+ mProtocols[index] = binder;
+ return this;
+ }
+
+ /**
+ * Sets optional extra media route service or protocol specific information about
+ * the connection. Use the service or protocol name as the prefix for
+ * any extras to avoid namespace collisions.
+ */
+ public @NonNull Builder setExtras(@Nullable Bundle extras) {
+ mExtras = extras;
+ return this;
+ }
+
+ /**
+ * Builds the {@link ConnectionInfo} object.
+ */
+ public @NonNull ConnectionInfo build() {
+ return new ConnectionInfo(mRoute,
+ mAudioAttributes, mPresentationDisplay,
+ mVolumeProvider, mProtocols, mExtras, mCloseables);
+ }
+ }
+ }
+
+ /**
+ * Describes one particular way of routing media content to a destination
+ * according to the capabilities specified by a media route selector on behalf
+ * of an application.
+ */
+ public static final class RouteInfo {
+ private final String mId;
+ private final DestinationInfo mDestination;
+ private final MediaRouteSelector mSelector;
+ private final int mFeatures;
+ private final ArrayList<String> mProtocols;
+ private final Bundle mExtras;
+
+ RouteInfo(String id, DestinationInfo destination, MediaRouteSelector selector,
+ int features, ArrayList<String> protocols, Bundle extras) {
+ mId = id;
+ mDestination = destination;
+ mSelector = selector;
+ mFeatures = features;
+ mProtocols = protocols;
+ mExtras = extras;
+ }
+
+ /**
+ * Gets the route's stable identifier.
+ * <p>
+ * The id is intended to uniquely identify the route among all routes that
+ * are offered by a particular destination in such a way that the client can
+ * refer to it at a later time.
+ * </p>
+ */
+ public @NonNull String getId() {
+ return mId;
+ }
+
+ /**
+ * Gets the destination that is offering this route.
+ */
+ public @NonNull DestinationInfo getDestination() {
+ return mDestination;
+ }
+
+ /**
+ * Gets the media route selector provided by the client for which this
+ * route was created.
+ * <p>
+ * It is implied that this route supports all of the required capabilities
+ * that were expressed in the selector.
+ * </p>
+ */
+ public @NonNull MediaRouteSelector getSelector() {
+ return mSelector;
+ }
+
+ /**
+ * Gets the set of supported route features.
+ */
+ public @RouteFeatures int getFeatures() {
+ return mFeatures;
+ }
+
+ /**
+ * Gets the list of supported route protocols.
+ * <p>
+ * Refer to <code>android.support.media.protocols.MediaRouteProtocol</code>
+ * for more information.
+ * </p>
+ */
+ public @NonNull List<String> getProtocols() {
+ return mProtocols;
+ }
+
+ /**
+ * Gets optional extra information about the route, or null if none.
+ */
+ public @Nullable Bundle getExtras() {
+ return mExtras;
+ }
+
+ @Override
+ public @NonNull String toString() {
+ return "RouteInfo{ id=" + mId + ", destination=" + mDestination
+ + ", features=0x" + Integer.toHexString(mFeatures)
+ + ", selector=" + mSelector + ", protocols=" + mProtocols
+ + ", extras=" + mExtras + " }";
+ }
+
+ /**
+ * Builds {@link RouteInfo} objects.
+ */
+ public static final class Builder {
+ private final DestinationInfo mDestination;
+ private final String mId;
+ private final MediaRouteSelector mSelector;
+ private int mFeatures;
+ private final ArrayList<String> mProtocols = new ArrayList<String>();
+ private Bundle mExtras;
+
+ /**
+ * Creates a builder for route information.
+ *
+ * @param id The route's stable identifier.
+ * @param destination The destination of this route.
+ * @param selector The media route selector provided by the client for which
+ * this route was created. This must be one of the selectors that was
+ * included in the discovery request.
+ */
+ public Builder(@NonNull String id, @NonNull DestinationInfo destination,
+ @NonNull MediaRouteSelector selector) {
+ if (TextUtils.isEmpty(id)) {
+ throw new IllegalArgumentException("id must not be null or empty");
+ }
+ if (destination == null) {
+ throw new IllegalArgumentException("destination must not be null");
+ }
+ if (selector == null) {
+ throw new IllegalArgumentException("selector must not be null");
+ }
+ mDestination = destination;
+ mId = id;
+ mSelector = selector;
+ }
+
+ /**
+ * Sets the set of supported route features.
+ */
+ public @NonNull Builder setFeatures(@RouteFeatures int features) {
+ mFeatures = features;
+ return this;
+ }
+
+ /**
+ * Adds a supported route protocol using its fully qualified class name.
+ * <p>
+ * If the protocol was not requested by the client in its selector
+ * then it will be silently discarded.
+ * </p>
+ */
+ public @NonNull <T extends IInterface> Builder addProtocol(@NonNull Class<T> clazz) {
+ if (clazz == null) {
+ throw new IllegalArgumentException("clazz must not be null");
+ }
+ return addProtocol(clazz.getName());
+ }
+
+ /**
+ * Adds a supported route protocol by name.
+ * <p>
+ * If the protocol was not requested by the client in its selector
+ * then it will be silently discarded.
+ * </p>
+ */
+ public @NonNull Builder addProtocol(@NonNull String name) {
+ if (TextUtils.isEmpty(name)) {
+ throw new IllegalArgumentException("name must not be null");
+ }
+ if (mSelector.containsProtocol(name)) {
+ mProtocols.add(name);
+ }
+ return this;
+ }
+
+ /**
+ * Sets optional extra information about the route, or null if none.
+ */
+ public @NonNull Builder setExtras(@Nullable Bundle extras) {
+ mExtras = extras;
+ return this;
+ }
+
+ /**
+ * Builds the {@link RouteInfo} object.
+ * <p>
+ * Ensures that all required protocols have been supplied.
+ * </p>
+ */
+ public @NonNull RouteInfo build() {
+ int missingFeatures = mSelector.getRequiredFeatures() & ~mFeatures;
+ if (missingFeatures != 0) {
+ throw new IllegalStateException("The media route selector "
+ + "specified required features which this route does "
+ + "not appear to support so it should not have been published: "
+ + "missing 0x" + Integer.toHexString(missingFeatures));
+ }
+ for (String protocol : mSelector.getRequiredProtocols()) {
+ if (!mProtocols.contains(protocol)) {
+ throw new IllegalStateException("The media route selector "
+ + "specified required protocols which this route "
+ + "does not appear to support so it should not have "
+ + "been published: missing " + protocol);
+ }
+ }
+ return new RouteInfo(mId, mDestination, mSelector,
+ mFeatures, mProtocols, mExtras);
+ }
+ }
+ }
+
+ /**
+ * Describes a destination for media content such as a device,
+ * an individual port on a device, or a group of devices.
+ */
+ public static final class DestinationInfo {
+ private final String mId;
+ private final ServiceMetadata mService;
+ private final CharSequence mName;
+ private final CharSequence mDescription;
+ private final int mIconResourceId;
+ private final Bundle mExtras;
+
+ DestinationInfo(String id, ServiceMetadata service,
+ CharSequence name, CharSequence description,
+ int iconResourceId, Bundle extras) {
+ mId = id;
+ mService = service;
+ mName = name;
+ mDescription = description;
+ mIconResourceId = iconResourceId;
+ mExtras = extras;
+ }
+
+ /**
+ * Gets the destination's stable identifier.
+ * <p>
+ * The id is intended to uniquely identify the destination among all destinations
+ * provided by the media route service in such a way that the client can
+ * refer to it at a later time. Ideally, the id should be resilient to
+ * user-initiated actions such as changes to the name or description
+ * of the destination.
+ * </p>
+ */
+ public @NonNull String getId() {
+ return mId;
+ }
+
+ /**
+ * Gets metadata about the service that is providing access to this destination.
+ */
+ public @NonNull ServiceMetadata getServiceMetadata() {
+ return mService;
+ }
+
+ /**
+ * Gets the destination's name for display to the user.
+ */
+ public @NonNull CharSequence getName() {
+ return mName;
+ }
+
+ /**
+ * Gets the destination's description for display to the user, or null if none.
+ */
+ public @Nullable CharSequence getDescription() {
+ return mDescription;
+ }
+
+ /**
+ * Gets an icon resource from the service's package which is used
+ * to identify the destination, or -1 if none.
+ */
+ public @DrawableRes int getIconResourceId() {
+ return mIconResourceId;
+ }
+
+ /**
+ * Loads the icon drawable, or null if none.
+ */
+ public @Nullable Drawable loadIcon(@NonNull PackageManager pm) {
+ return mIconResourceId >= 0 ? mService.getDrawable(pm, mIconResourceId) : null;
+ }
+
+ /**
+ * Gets optional extra information about the destination, or null if none.
+ */
+ public @Nullable Bundle getExtras() {
+ return mExtras;
+ }
+
+ @Override
+ public @NonNull String toString() {
+ return "DestinationInfo{ id=" + mId + ", service=" + mService + ", name=" + mName
+ + ", description=" + mDescription + ", iconResourceId=" + mIconResourceId
+ + ", extras=" + mExtras + " }";
+ }
+
+ /**
+ * Builds {@link DestinationInfo} objects.
+ */
+ public static final class Builder {
+ private final String mId;
+ private final ServiceMetadata mService;
+ private final CharSequence mName;
+ private CharSequence mDescription;
+ private int mIconResourceId = -1;
+ private Bundle mExtras;
+
+ /**
+ * Creates a builder for destination information.
+ *
+ * @param id The destination's stable identifier.
+ * @param service Metatada about the service that is providing access to
+ * this destination.
+ * @param name The destination's name for display to the user.
+ */
+ public Builder(@NonNull String id, @NonNull ServiceMetadata service,
+ @NonNull CharSequence name) {
+ if (TextUtils.isEmpty(id)) {
+ throw new IllegalArgumentException("id must not be null or empty");
+ }
+ if (service == null) {
+ throw new IllegalArgumentException("service must not be null");
+ }
+ if (TextUtils.isEmpty(name)) {
+ throw new IllegalArgumentException("name must not be null or empty");
+ }
+ mId = id;
+ mService = service;
+ mName = name;
+ }
+
+ /**
+ * Sets the destination's description for display to the user, or null if none.
+ */
+ public @NonNull Builder setDescription(@Nullable CharSequence description) {
+ mDescription = description;
+ return this;
+ }
+
+ /**
+ * Sets an icon resource from this package used to identify the destination,
+ * or -1 if none.
+ */
+ public @NonNull Builder setIconResourceId(@DrawableRes int resid) {
+ mIconResourceId = resid;
+ return this;
+ }
+
+ /**
+ * Gets optional extra information about the destination, or null if none.
+ */
+ public @NonNull Builder setExtras(@Nullable Bundle extras) {
+ mExtras = extras;
+ return this;
+ }
+
+ /**
+ * Builds the {@link DestinationInfo} object.
+ */
+ public @NonNull DestinationInfo build() {
+ return new DestinationInfo(mId, mService, mName, mDescription,
+ mIconResourceId, mExtras);
+ }
+ }
+ }
+
+ /**
+ * Describes metadata about a {@link MediaRouteService} which is providing
+ * access to certain kinds of destinations.
+ */
+ public static final class ServiceMetadata {
+ private final ServiceInfo mService;
+ private CharSequence mLabel;
+ private Drawable mIcon;
+
+ ServiceMetadata(Service service) throws NameNotFoundException {
+ mService = service.getPackageManager().getServiceInfo(
+ new ComponentName(service, service.getClass()),
+ PackageManager.GET_META_DATA);
+ }
+
+ ServiceMetadata(ServiceInfo service) {
+ mService = service;
+ }
+
+ /**
+ * Gets the service's component information including it name, label and icon.
+ */
+ public @NonNull ServiceInfo getService() {
+ return mService;
+ }
+
+ /**
+ * Gets the service's component name.
+ */
+ public @NonNull ComponentName getComponentName() {
+ return new ComponentName(mService.packageName, mService.name);
+ }
+
+ /**
+ * Gets the service's package name.
+ */
+ public @NonNull String getPackageName() {
+ return mService.packageName;
+ }
+
+ /**
+ * Gets the service's name for display to the user, or null if none.
+ */
+ public @NonNull CharSequence getLabel(@NonNull PackageManager pm) {
+ if (mLabel == null) {
+ mLabel = mService.loadLabel(pm);
+ }
+ return mLabel;
+ }
+
+ /**
+ * Gets the icon drawable, or null if none.
+ */
+ public @Nullable Drawable getIcon(@NonNull PackageManager pm) {
+ if (mIcon == null) {
+ mIcon = mService.loadIcon(pm);
+ }
+ return mIcon;
+ }
+
+ // TODO: add service metadata
+
+ Drawable getDrawable(PackageManager pm, int resid) {
+ return pm.getDrawable(getPackageName(), resid, mService.applicationInfo);
+ }
+
+ @Override
+ public @NonNull String toString() {
+ return "ServiceInfo{ service=" + getComponentName().toShortString() + " }";
+ }
+ }
+
+ /**
+ * Describes a request to discover routes on behalf of an application.
+ */
+ public static final class DiscoveryRequest {
+ private final ArrayList<MediaRouteSelector> mSelectors =
+ new ArrayList<MediaRouteSelector>();
+ private int mFlags;
+
+ DiscoveryRequest(@NonNull List<MediaRouteSelector> selectors) {
+ setSelectors(selectors);
+ }
+
+ /**
+ * Sets the list of media route selectors to consider during discovery.
+ */
+ public void setSelectors(@NonNull List<MediaRouteSelector> selectors) {
+ if (selectors == null) {
+ throw new IllegalArgumentException("selectors");
+ }
+ mSelectors.clear();
+ mSelectors.addAll(selectors);
+ }
+
+ /**
+ * Gets the list of media route selectors to consider during discovery.
+ */
+ public @NonNull List<MediaRouteSelector> getSelectors() {
+ return mSelectors;
+ }
+
+ /**
+ * Gets discovery flags, such as {@link MediaRouter#DISCOVERY_FLAG_BACKGROUND}.
+ */
+ public @DiscoveryFlags int getFlags() {
+ return mFlags;
+ }
+
+ /**
+ * Sets discovery flags, such as {@link MediaRouter#DISCOVERY_FLAG_BACKGROUND}.
+ */
+ public void setFlags(@DiscoveryFlags int flags) {
+ mFlags = flags;
+ }
+
+ @Override
+ public @NonNull String toString() {
+ return "DiscoveryRequest{ selectors=" + mSelectors
+ + ", flags=0x" + Integer.toHexString(mFlags)
+ + " }";
+ }
+ }
+
+ /**
+ * Describes a request to connect to a previously discovered route on
+ * behalf of an application.
+ */
+ public static final class ConnectionRequest {
+ private RouteInfo mRoute;
+ private int mFlags;
+ private Bundle mExtras;
+
+ ConnectionRequest(@NonNull RouteInfo route) {
+ setRoute(route);
+ }
+
+ /**
+ * Gets the route to which to connect.
+ */
+ public @NonNull RouteInfo getRoute() {
+ return mRoute;
+ }
+
+ /**
+ * Sets the route to which to connect.
+ */
+ public void setRoute(@NonNull RouteInfo route) {
+ if (route == null) {
+ throw new IllegalArgumentException("route must not be null");
+ }
+ mRoute = route;
+ }
+
+ /**
+ * Gets connection flags, such as {@link MediaRouter#CONNECTION_FLAG_BARGE}.
+ */
+ public @ConnectionFlags int getFlags() {
+ return mFlags;
+ }
+
+ /**
+ * Sets connection flags, such as {@link MediaRouter#CONNECTION_FLAG_BARGE}.
+ */
+ public void setFlags(@ConnectionFlags int flags) {
+ mFlags = flags;
+ }
+
+ /**
+ * Gets optional extras supplied by the application as part of the call to
+ * connect, or null if none. The media route service may use this
+ * information to configure the route during connection.
+ */
+ public @Nullable Bundle getExtras() {
+ return mExtras;
+ }
+
+ /**
+ * Sets optional extras supplied by the application as part of the call to
+ * connect, or null if none. The media route service may use this
+ * information to configure the route during connection.
+ */
+ public void setExtras(@Nullable Bundle extras) {
+ mExtras = extras;
+ }
+
+ @Override
+ public @NonNull String toString() {
+ return "ConnectionRequest{ route=" + mRoute
+ + ", flags=0x" + Integer.toHexString(mFlags)
+ + ", extras=" + mExtras + " }";
+ }
+ }
+
+ /**
+ * Callback interface to specify policy for route discovery, filtering,
+ * and connection establishment as well as observe media router state changes.
+ */
+ public static abstract class RoutingCallback extends StateCallback {
+ /**
+ * Called to prepare a discovery request object to specify the desired
+ * media route selectors when the media router has been asked to start discovery.
+ * <p>
+ * By default, the discovery request contains all of the selectors which
+ * have been added to the media router. Subclasses may override the list of
+ * selectors by modifying the discovery request object before returning.
+ * </p>
+ *
+ * @param request The discovery request object which may be modified by
+ * this method to alter how discovery will be performed.
+ * @param selectors The immutable list of media route selectors which were
+ * added to the media router.
+ * @return True to allow discovery to proceed or false to abort it.
+ * By default, this methods returns true.
+ */
+ public boolean onPrepareDiscoveryRequest(@NonNull DiscoveryRequest request,
+ @NonNull List<MediaRouteSelector> selectors) {
+ return true;
+ }
+
+ /**
+ * Called to prepare a connection request object to specify the desired
+ * route and connection parameters when the media router has been asked to
+ * connect to a particular destination.
+ * <p>
+ * By default, the connection request specifies the first available route
+ * to the destination. Subclasses may override the route and destination
+ * or set additional connection parameters by modifying the connection request
+ * object before returning.
+ * </p>
+ *
+ * @param request The connection request object which may be modified by
+ * this method to alter how the connection will be established.
+ * @param destination The destination to which the media router was asked
+ * to connect.
+ * @param routes The list of routes that belong to that destination sorted
+ * in the same order as their matching media route selectors which were
+ * used during discovery.
+ * @return True to allow the connection to proceed or false to abort it.
+ * By default, this methods returns true.
+ */
+ public boolean onPrepareConnectionRequest(
+ @NonNull ConnectionRequest request,
+ @NonNull DestinationInfo destination, @NonNull List<RouteInfo> routes) {
+ return true;
+ }
+ }
+
+ /**
+ * Callback class to receive events from a {@link MediaRouter.Delegate}.
+ */
+ public static abstract class StateCallback {
+ /**
+ * Called when the media router has been released.
+ */
+ public void onReleased() { }
+
+ /**
+ * Called when the discovery state has changed.
+ *
+ * @param state The new discovery state: one of
+ * {@link #DISCOVERY_STATE_STOPPED} or {@link #DISCOVERY_STATE_STARTED}.
+ */
+ public void onDiscoveryStateChanged(@DiscoveryState int state) { }
+
+ /**
+ * Called when the connection state has changed.
+ *
+ * @param state The new connection state: one of
+ * {@link #CONNECTION_STATE_DISCONNECTED}, {@link #CONNECTION_STATE_CONNECTING}
+ * or {@link #CONNECTION_STATE_CONNECTED}.
+ */
+ public void onConnectionStateChanged(@ConnectionState int state) { }
+
+ /**
+ * Called when the selected destination has changed.
+ *
+ * @param destination The new selected destination, or null if none.
+ */
+ public void onSelectedDestinationChanged(@Nullable DestinationInfo destination) { }
+
+ /**
+ * Called when route discovery has started.
+ */
+ public void onDiscoveryStarted() { }
+
+ /**
+ * Called when route discovery has stopped normally.
+ * <p>
+ * Abnormal termination is reported via {@link #onDiscoveryFailed}.
+ * </p>
+ */
+ public void onDiscoveryStopped() { }
+
+ /**
+ * Called when discovery has failed in a non-recoverable manner.
+ *
+ * @param error The error code: one of
+ * {@link MediaRouter#DISCOVERY_ERROR_UNKNOWN},
+ * {@link MediaRouter#DISCOVERY_ERROR_ABORTED},
+ * or {@link MediaRouter#DISCOVERY_ERROR_NO_CONNECTIVITY}.
+ * @param message The localized error message, or null if none. This message
+ * may be shown to the user.
+ * @param extras Additional information about the error which a client
+ * may use, or null if none.
+ */
+ public void onDiscoveryFailed(@DiscoveryError int error, @Nullable CharSequence message,
+ @Nullable Bundle extras) { }
+
+ /**
+ * Called when a new destination is found or has changed during discovery.
+ * <p>
+ * Certain destinations may be omitted because they have been filtered
+ * out by the media router's routing callback.
+ * </p>
+ *
+ * @param destination The destination that was found.
+ */
+ public void onDestinationFound(@NonNull DestinationInfo destination) { }
+
+ /**
+ * Called when a destination is no longer reachable or is no longer
+ * offering any routes that satisfy the discovery request.
+ *
+ * @param destination The destination that went away.
+ */
+ public void onDestinationLost(@NonNull DestinationInfo destination) { }
+
+ /**
+ * Called when a connection attempt begins.
+ */
+ public void onConnecting() { }
+
+ /**
+ * Called when the connection succeeds.
+ */
+ public void onConnected() { }
+
+ /**
+ * Called when the connection is terminated normally.
+ * <p>
+ * Abnormal termination is reported via {@link #onConnectionFailed}.
+ * </p>
+ */
+ public void onDisconnected() { }
+
+ /**
+ * Called when a connection attempt or connection in
+ * progress has failed in a non-recoverable manner.
+ *
+ * @param error The error code: one of
+ * {@link MediaRouter#CONNECTION_ERROR_ABORTED},
+ * {@link MediaRouter#CONNECTION_ERROR_UNAUTHORIZED},
+ * {@link MediaRouter#CONNECTION_ERROR_UNREACHABLE},
+ * {@link MediaRouter#CONNECTION_ERROR_BUSY},
+ * {@link MediaRouter#CONNECTION_ERROR_TIMEOUT},
+ * {@link MediaRouter#CONNECTION_ERROR_BROKEN},
+ * or {@link MediaRouter#CONNECTION_ERROR_BARGED}.
+ * @param message The localized error message, or null if none. This message
+ * may be shown to the user.
+ * @param extras Additional information about the error which a client
+ * may use, or null if none.
+ */
+ public void onConnectionFailed(@ConnectionError int error,
+ @Nullable CharSequence message, @Nullable Bundle extras) { }
+ }
+}
diff --git a/media/java/android/media/routing/ParcelableConnectionInfo.aidl b/media/java/android/media/routing/ParcelableConnectionInfo.aidl
new file mode 100644
index 0000000..4a9ec94
--- /dev/null
+++ b/media/java/android/media/routing/ParcelableConnectionInfo.aidl
@@ -0,0 +1,18 @@
+/* Copyright 2014, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+
+package android.media.routing;
+
+parcelable ParcelableConnectionInfo;
diff --git a/media/java/android/media/routing/ParcelableConnectionInfo.java b/media/java/android/media/routing/ParcelableConnectionInfo.java
new file mode 100644
index 0000000..45cfe9f
--- /dev/null
+++ b/media/java/android/media/routing/ParcelableConnectionInfo.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.media.routing;
+
+import android.media.AudioAttributes;
+import android.os.Bundle;
+import android.os.IBinder;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+/**
+ * Internal parcelable representation of a media route connection.
+ */
+class ParcelableConnectionInfo implements Parcelable {
+ public AudioAttributes audioAttributes;
+ public int presentationDisplayId = -1;
+ // todo: volume
+ public IBinder[] protocolBinders;
+ public Bundle extras;
+
+ public static final Parcelable.Creator<ParcelableConnectionInfo> CREATOR =
+ new Parcelable.Creator<ParcelableConnectionInfo>() {
+ @Override
+ public ParcelableConnectionInfo createFromParcel(Parcel source) {
+ ParcelableConnectionInfo info = new ParcelableConnectionInfo();
+ if (source.readInt() != 0) {
+ info.audioAttributes = AudioAttributes.CREATOR.createFromParcel(source);
+ }
+ info.presentationDisplayId = source.readInt();
+ info.protocolBinders = source.createBinderArray();
+ info.extras = source.readBundle();
+ return info;
+ }
+
+ @Override
+ public ParcelableConnectionInfo[] newArray(int size) {
+ return new ParcelableConnectionInfo[size];
+ }
+ };
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ if (audioAttributes != null) {
+ dest.writeInt(1);
+ audioAttributes.writeToParcel(dest, flags);
+ } else {
+ dest.writeInt(0);
+ }
+ dest.writeInt(presentationDisplayId);
+ dest.writeBinderArray(protocolBinders);
+ dest.writeBundle(extras);
+ }
+}
diff --git a/media/java/android/media/routing/ParcelableDestinationInfo.aidl b/media/java/android/media/routing/ParcelableDestinationInfo.aidl
new file mode 100644
index 0000000..bf1c198
--- /dev/null
+++ b/media/java/android/media/routing/ParcelableDestinationInfo.aidl
@@ -0,0 +1,18 @@
+/* Copyright 2014, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+
+package android.media.routing;
+
+parcelable ParcelableDestinationInfo;
diff --git a/media/java/android/media/routing/ParcelableDestinationInfo.java b/media/java/android/media/routing/ParcelableDestinationInfo.java
new file mode 100644
index 0000000..eca5eec
--- /dev/null
+++ b/media/java/android/media/routing/ParcelableDestinationInfo.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.media.routing;
+
+import android.os.Bundle;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.text.TextUtils;
+
+/**
+ * Internal parcelable representation of a media destination.
+ */
+class ParcelableDestinationInfo implements Parcelable {
+ public String id;
+ public CharSequence name;
+ public CharSequence description;
+ public int iconResourceId;
+ public Bundle extras;
+
+ public static final Parcelable.Creator<ParcelableDestinationInfo> CREATOR =
+ new Parcelable.Creator<ParcelableDestinationInfo>() {
+ @Override
+ public ParcelableDestinationInfo createFromParcel(Parcel source) {
+ ParcelableDestinationInfo info = new ParcelableDestinationInfo();
+ info.id = source.readString();
+ info.name = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(source);
+ info.description = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(source);
+ info.iconResourceId = source.readInt();
+ info.extras = source.readBundle();
+ return info;
+ }
+
+ @Override
+ public ParcelableDestinationInfo[] newArray(int size) {
+ return new ParcelableDestinationInfo[size];
+ }
+ };
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ dest.writeString(id);
+ TextUtils.writeToParcel(name, dest, flags);
+ TextUtils.writeToParcel(description, dest, flags);
+ dest.writeInt(iconResourceId);
+ dest.writeBundle(extras);
+ }
+}
diff --git a/media/java/android/media/routing/ParcelableRouteInfo.aidl b/media/java/android/media/routing/ParcelableRouteInfo.aidl
new file mode 100644
index 0000000..126afaa
--- /dev/null
+++ b/media/java/android/media/routing/ParcelableRouteInfo.aidl
@@ -0,0 +1,18 @@
+/* Copyright 2014, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+
+package android.media.routing;
+
+parcelable ParcelableRouteInfo;
diff --git a/media/java/android/media/routing/ParcelableRouteInfo.java b/media/java/android/media/routing/ParcelableRouteInfo.java
new file mode 100644
index 0000000..fb1a547
--- /dev/null
+++ b/media/java/android/media/routing/ParcelableRouteInfo.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.media.routing;
+
+import android.os.Bundle;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+/**
+ * Internal parcelable representation of a media route.
+ */
+class ParcelableRouteInfo implements Parcelable {
+ public String id;
+ public int selectorIndex; // index of selector within list used for discovery
+ public int features;
+ public String[] protocols;
+ public Bundle extras;
+
+ public static final Parcelable.Creator<ParcelableRouteInfo> CREATOR =
+ new Parcelable.Creator<ParcelableRouteInfo>() {
+ @Override
+ public ParcelableRouteInfo createFromParcel(Parcel source) {
+ ParcelableRouteInfo info = new ParcelableRouteInfo();
+ info.id = source.readString();
+ info.selectorIndex = source.readInt();
+ info.features = source.readInt();
+ info.protocols = source.createStringArray();
+ info.extras = source.readBundle();
+ return info;
+ }
+
+ @Override
+ public ParcelableRouteInfo[] newArray(int size) {
+ return new ParcelableRouteInfo[size];
+ }
+ };
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ dest.writeString(id);
+ dest.writeInt(selectorIndex);
+ dest.writeInt(features);
+ dest.writeStringArray(protocols);
+ dest.writeBundle(extras);
+ }
+}
diff --git a/media/java/android/media/session/ISession.aidl b/media/java/android/media/session/ISession.aidl
index bd0019f..af3b72e 100644
--- a/media/java/android/media/session/ISession.aidl
+++ b/media/java/android/media/session/ISession.aidl
@@ -19,6 +19,7 @@
import android.content.pm.ParceledListSlice;
import android.media.AudioAttributes;
import android.media.MediaMetadata;
+import android.media.routing.IMediaRouter;
import android.media.session.ISessionController;
import android.media.session.PlaybackState;
import android.media.session.MediaSession;
@@ -34,6 +35,7 @@
ISessionController getController();
void setFlags(int flags);
void setActive(boolean active);
+ void setMediaRouter(in IMediaRouter router);
void setMediaButtonReceiver(in PendingIntent mbr);
void setLaunchPendingIntent(in PendingIntent pi);
void destroy();
diff --git a/media/java/android/media/session/ISessionController.aidl b/media/java/android/media/session/ISessionController.aidl
index d684688..e2d06d3 100644
--- a/media/java/android/media/session/ISessionController.aidl
+++ b/media/java/android/media/session/ISessionController.aidl
@@ -20,6 +20,8 @@
import android.content.pm.ParceledListSlice;
import android.media.MediaMetadata;
import android.media.Rating;
+import android.media.routing.IMediaRouterDelegate;
+import android.media.routing.IMediaRouterStateCallback;
import android.media.session.ISessionControllerCallback;
import android.media.session.ParcelableVolumeInfo;
import android.media.session.PlaybackState;
@@ -49,6 +51,8 @@
void adjustVolume(int direction, int flags, String packageName);
void setVolumeTo(int value, int flags, String packageName);
+ IMediaRouterDelegate createMediaRouterDelegate(IMediaRouterStateCallback callback);
+
// These commands are for the TransportControls
void play();
void playFromMediaId(String uri, in Bundle extras);
diff --git a/media/java/android/media/session/MediaController.java b/media/java/android/media/session/MediaController.java
index dd6bd20..c23a139 100644
--- a/media/java/android/media/session/MediaController.java
+++ b/media/java/android/media/session/MediaController.java
@@ -26,6 +26,7 @@
import android.media.MediaMetadata;
import android.media.Rating;
import android.media.VolumeProvider;
+import android.media.routing.MediaRouter;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
@@ -119,6 +120,17 @@
}
/**
+ * Creates a media router delegate through which the destination of the media
+ * router may be observed and controlled.
+ *
+ * @return The media router delegate, or null if the media session does
+ * not support media routing.
+ */
+ public @Nullable MediaRouter.Delegate createMediaRouterDelegate() {
+ return new MediaRouter.Delegate();
+ }
+
+ /**
* Send the specified media button event to the session. Only media keys can
* be sent by this method, other keys will be ignored.
*
diff --git a/media/java/android/media/session/MediaSession.java b/media/java/android/media/session/MediaSession.java
index 973527f..bd0c619 100644
--- a/media/java/android/media/session/MediaSession.java
+++ b/media/java/android/media/session/MediaSession.java
@@ -29,6 +29,7 @@
import android.media.MediaMetadata;
import android.media.Rating;
import android.media.VolumeProvider;
+import android.media.routing.MediaRouter;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
@@ -221,6 +222,23 @@
}
/**
+ * Associates a {@link MediaRouter} with this session to control the destination
+ * of media content.
+ * <p>
+ * A media router may only be associated with at most one session at a time.
+ * </p>
+ *
+ * @param router The media router, or null to remove the current association.
+ */
+ public void setMediaRouter(@Nullable MediaRouter router) {
+ try {
+ mBinder.setMediaRouter(router != null ? router.getBinder() : null);
+ } catch (RemoteException e) {
+ Log.wtf(TAG, "Failure in setMediaButtonReceiver.", e);
+ }
+ }
+
+ /**
* Set a pending intent for your media button receiver to allow restarting
* playback after the session has been stopped. If your app is started in
* this way an {@link Intent#ACTION_MEDIA_BUTTON} intent will be sent via
diff --git a/media/jni/Android.mk b/media/jni/Android.mk
index 90fe695..4ebbe26 100644
--- a/media/jni/Android.mk
+++ b/media/jni/Android.mk
@@ -64,7 +64,7 @@
$(PV_INCLUDES) \
$(JNI_H_INCLUDE)
-LOCAL_CFLAGS +=
+LOCAL_CFLAGS += -Wall -Werror -Wunused -Wunreachable-code
LOCAL_MODULE:= libmedia_jni
diff --git a/media/jni/android_media_AmrInputStream.cpp b/media/jni/android_media_AmrInputStream.cpp
index 3df6530..afb5d5c 100644
--- a/media/jni/android_media_AmrInputStream.cpp
+++ b/media/jni/android_media_AmrInputStream.cpp
@@ -50,7 +50,7 @@
};
static jlong android_media_AmrInputStream_GsmAmrEncoderNew
- (JNIEnv *env, jclass clazz) {
+ (JNIEnv *env, jclass /* clazz */) {
GsmAmrEncoderState* gae = new GsmAmrEncoderState();
if (gae == NULL) {
jniThrowRuntimeException(env, "Out of memory");
@@ -59,7 +59,7 @@
}
static void android_media_AmrInputStream_GsmAmrEncoderInitialize
- (JNIEnv *env, jclass clazz, jlong gae) {
+ (JNIEnv *env, jclass /* clazz */, jlong gae) {
GsmAmrEncoderState *state = (GsmAmrEncoderState *) gae;
int32_t nResult = AMREncodeInit(&state->mEncState, &state->mSidState, false);
if (nResult != OK) {
@@ -69,7 +69,7 @@
}
static jint android_media_AmrInputStream_GsmAmrEncoderEncode
- (JNIEnv *env, jclass clazz,
+ (JNIEnv *env, jclass /* clazz */,
jlong gae, jbyteArray pcm, jint pcmOffset, jbyteArray amr, jint amrOffset) {
jbyte inBuf[BYTES_PER_FRAME];
@@ -105,7 +105,7 @@
}
static void android_media_AmrInputStream_GsmAmrEncoderCleanup
- (JNIEnv *env, jclass clazz, jlong gae) {
+ (JNIEnv* /* env */, jclass /* clazz */, jlong gae) {
GsmAmrEncoderState *state = (GsmAmrEncoderState *) gae;
AMREncodeExit(&state->mEncState, &state->mSidState);
state->mEncState = NULL;
@@ -113,7 +113,7 @@
}
static void android_media_AmrInputStream_GsmAmrEncoderDelete
- (JNIEnv *env, jclass clazz, jlong gae) {
+ (JNIEnv* /* env */, jclass /* clazz */, jlong gae) {
delete (GsmAmrEncoderState*)gae;
}
diff --git a/media/jni/android_media_ImageReader.cpp b/media/jni/android_media_ImageReader.cpp
index 7830c80..0a6bf1e 100644
--- a/media/jni/android_media_ImageReader.cpp
+++ b/media/jni/android_media_ImageReader.cpp
@@ -502,7 +502,6 @@
case HAL_PIXEL_FORMAT_Y8:
// Single plane 8bpp data.
ALOG_ASSERT(idx == 0, "Wrong index: %d", idx);
- pixelStride;
break;
case HAL_PIXEL_FORMAT_YV12:
pixelStride = 1;
diff --git a/media/jni/android_media_MediaCodecList.cpp b/media/jni/android_media_MediaCodecList.cpp
index 12eb7d2..f8c349b 100644
--- a/media/jni/android_media_MediaCodecList.cpp
+++ b/media/jni/android_media_MediaCodecList.cpp
@@ -42,7 +42,7 @@
}
static jint android_media_MediaCodecList_getCodecCount(
- JNIEnv *env, jobject thiz) {
+ JNIEnv *env, jobject /* thiz */) {
sp<IMediaCodecList> mcl = getCodecList(env);
if (mcl == NULL) {
// Runtime exception already pending.
@@ -52,7 +52,7 @@
}
static jstring android_media_MediaCodecList_getCodecName(
- JNIEnv *env, jobject thiz, jint index) {
+ JNIEnv *env, jobject /* thiz */, jint index) {
sp<IMediaCodecList> mcl = getCodecList(env);
if (mcl == NULL) {
// Runtime exception already pending.
@@ -70,7 +70,7 @@
}
static jint android_media_MediaCodecList_findCodecByName(
- JNIEnv *env, jobject thiz, jstring name) {
+ JNIEnv *env, jobject /* thiz */, jstring name) {
if (name == NULL) {
jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
return -ENOENT;
@@ -95,7 +95,7 @@
}
static jboolean android_media_MediaCodecList_isEncoder(
- JNIEnv *env, jobject thiz, jint index) {
+ JNIEnv *env, jobject /* thiz */, jint index) {
sp<IMediaCodecList> mcl = getCodecList(env);
if (mcl == NULL) {
// Runtime exception already pending.
@@ -112,7 +112,7 @@
}
static jarray android_media_MediaCodecList_getSupportedTypes(
- JNIEnv *env, jobject thiz, jint index) {
+ JNIEnv *env, jobject /* thiz */, jint index) {
sp<IMediaCodecList> mcl = getCodecList(env);
if (mcl == NULL) {
// Runtime exception already pending.
@@ -144,7 +144,7 @@
}
static jobject android_media_MediaCodecList_getCodecCapabilities(
- JNIEnv *env, jobject thiz, jint index, jstring type) {
+ JNIEnv *env, jobject /* thiz */, jint index, jstring type) {
if (type == NULL) {
jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
return NULL;
@@ -262,7 +262,7 @@
return caps;
}
-static void android_media_MediaCodecList_native_init(JNIEnv *env) {
+static void android_media_MediaCodecList_native_init(JNIEnv* /* env */) {
}
static JNINativeMethod gMethods[] = {
diff --git a/media/jni/android_media_MediaCrypto.cpp b/media/jni/android_media_MediaCrypto.cpp
index a6f8dcd..d2216fb 100644
--- a/media/jni/android_media_MediaCrypto.cpp
+++ b/media/jni/android_media_MediaCrypto.cpp
@@ -224,7 +224,7 @@
}
static jboolean android_media_MediaCrypto_isCryptoSchemeSupportedNative(
- JNIEnv *env, jobject thiz, jbyteArray uuidObj) {
+ JNIEnv *env, jobject /* thiz */, jbyteArray uuidObj) {
jsize uuidLength = env->GetArrayLength(uuidObj);
if (uuidLength != 16) {
diff --git a/media/jni/android_media_MediaDrm.cpp b/media/jni/android_media_MediaDrm.cpp
index 8e07ec0..d9de7a9 100644
--- a/media/jni/android_media_MediaDrm.cpp
+++ b/media/jni/android_media_MediaDrm.cpp
@@ -667,7 +667,7 @@
}
static jboolean android_media_MediaDrm_isCryptoSchemeSupportedNative(
- JNIEnv *env, jobject thiz, jbyteArray uuidObj, jstring jmimeType) {
+ JNIEnv *env, jobject /* thiz */, jbyteArray uuidObj, jstring jmimeType) {
if (uuidObj == NULL) {
jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
@@ -1173,7 +1173,7 @@
}
static void android_media_MediaDrm_setCipherAlgorithmNative(
- JNIEnv *env, jobject thiz, jobject jdrm, jbyteArray jsessionId,
+ JNIEnv *env, jobject /* thiz */, jobject jdrm, jbyteArray jsessionId,
jstring jalgorithm) {
sp<IDrm> drm = GetDrm(env, jdrm);
@@ -1197,7 +1197,7 @@
}
static void android_media_MediaDrm_setMacAlgorithmNative(
- JNIEnv *env, jobject thiz, jobject jdrm, jbyteArray jsessionId,
+ JNIEnv *env, jobject /* thiz */, jobject jdrm, jbyteArray jsessionId,
jstring jalgorithm) {
sp<IDrm> drm = GetDrm(env, jdrm);
@@ -1222,7 +1222,7 @@
static jbyteArray android_media_MediaDrm_encryptNative(
- JNIEnv *env, jobject thiz, jobject jdrm, jbyteArray jsessionId,
+ JNIEnv *env, jobject /* thiz */, jobject jdrm, jbyteArray jsessionId,
jbyteArray jkeyId, jbyteArray jinput, jbyteArray jiv) {
sp<IDrm> drm = GetDrm(env, jdrm);
@@ -1253,7 +1253,7 @@
}
static jbyteArray android_media_MediaDrm_decryptNative(
- JNIEnv *env, jobject thiz, jobject jdrm, jbyteArray jsessionId,
+ JNIEnv *env, jobject /* thiz */, jobject jdrm, jbyteArray jsessionId,
jbyteArray jkeyId, jbyteArray jinput, jbyteArray jiv) {
sp<IDrm> drm = GetDrm(env, jdrm);
@@ -1283,7 +1283,7 @@
}
static jbyteArray android_media_MediaDrm_signNative(
- JNIEnv *env, jobject thiz, jobject jdrm, jbyteArray jsessionId,
+ JNIEnv *env, jobject /* thiz */, jobject jdrm, jbyteArray jsessionId,
jbyteArray jkeyId, jbyteArray jmessage) {
sp<IDrm> drm = GetDrm(env, jdrm);
@@ -1313,7 +1313,7 @@
}
static jboolean android_media_MediaDrm_verifyNative(
- JNIEnv *env, jobject thiz, jobject jdrm, jbyteArray jsessionId,
+ JNIEnv *env, jobject /* thiz */, jobject jdrm, jbyteArray jsessionId,
jbyteArray jkeyId, jbyteArray jmessage, jbyteArray jsignature) {
sp<IDrm> drm = GetDrm(env, jdrm);
@@ -1342,7 +1342,7 @@
static jbyteArray android_media_MediaDrm_signRSANative(
- JNIEnv *env, jobject thiz, jobject jdrm, jbyteArray jsessionId,
+ JNIEnv *env, jobject /* thiz */, jobject jdrm, jbyteArray jsessionId,
jstring jalgorithm, jbyteArray jwrappedKey, jbyteArray jmessage) {
sp<IDrm> drm = GetDrm(env, jdrm);
diff --git a/media/jni/android_media_MediaMetadataRetriever.cpp b/media/jni/android_media_MediaMetadataRetriever.cpp
index fbe5340..c755bf0 100644
--- a/media/jni/android_media_MediaMetadataRetriever.cpp
+++ b/media/jni/android_media_MediaMetadataRetriever.cpp
@@ -33,6 +33,7 @@
#include "android_media_Utils.h"
#include "android_util_Binder.h"
+#include "android/graphics/GraphicsJNI.h"
using namespace android;
@@ -77,7 +78,6 @@
static void setRetriever(JNIEnv* env, jobject thiz, MediaMetadataRetriever* retriever)
{
// No lock is needed, since it is called internally by other methods that are protected
- MediaMetadataRetriever *old = (MediaMetadataRetriever*) env->GetLongField(thiz, fields.context);
env->SetLongField(thiz, fields.context, (jlong) retriever);
}
@@ -255,7 +255,7 @@
jobject config = env->CallStaticObjectMethod(
fields.configClazz,
fields.createConfigMethod,
- SkBitmap::kRGB_565_Config);
+ GraphicsJNI::colorTypeToLegacyBitmapConfig(kRGB_565_SkColorType));
uint32_t width, height;
bool swapWidthAndHeight = false;
diff --git a/media/jni/android_media_MediaMuxer.cpp b/media/jni/android_media_MediaMuxer.cpp
index 3fef446f..f234a1b 100644
--- a/media/jni/android_media_MediaMuxer.cpp
+++ b/media/jni/android_media_MediaMuxer.cpp
@@ -41,7 +41,7 @@
using namespace android;
static jint android_media_MediaMuxer_addTrack(
- JNIEnv *env, jclass clazz, jlong nativeObject, jobjectArray keys,
+ JNIEnv *env, jclass /* clazz */, jlong nativeObject, jobjectArray keys,
jobjectArray values) {
sp<MediaMuxer> muxer(reinterpret_cast<MediaMuxer *>(nativeObject));
if (muxer == NULL) {
@@ -71,7 +71,7 @@
}
static void android_media_MediaMuxer_writeSampleData(
- JNIEnv *env, jclass clazz, jlong nativeObject, jint trackIndex,
+ JNIEnv *env, jclass /* clazz */, jlong nativeObject, jint trackIndex,
jobject byteBuf, jint offset, jint size, jlong timeUs, jint flags) {
sp<MediaMuxer> muxer(reinterpret_cast<MediaMuxer *>(nativeObject));
if (muxer == NULL) {
@@ -146,7 +146,7 @@
}
static void android_media_MediaMuxer_setOrientationHint(
- JNIEnv *env, jclass clazz, jlong nativeObject, jint degrees) {
+ JNIEnv *env, jclass /* clazz */, jlong nativeObject, jint degrees) {
sp<MediaMuxer> muxer(reinterpret_cast<MediaMuxer *>(nativeObject));
if (muxer == NULL) {
jniThrowException(env, "java/lang/IllegalStateException",
@@ -164,7 +164,7 @@
}
static void android_media_MediaMuxer_setLocation(
- JNIEnv *env, jclass clazz, jlong nativeObject, jint latitude, jint longitude) {
+ JNIEnv *env, jclass /* clazz */, jlong nativeObject, jint latitude, jint longitude) {
MediaMuxer* muxer = reinterpret_cast<MediaMuxer *>(nativeObject);
status_t res = muxer->setLocation(latitude, longitude);
@@ -175,7 +175,7 @@
}
}
-static void android_media_MediaMuxer_start(JNIEnv *env, jclass clazz,
+static void android_media_MediaMuxer_start(JNIEnv *env, jclass /* clazz */,
jlong nativeObject) {
sp<MediaMuxer> muxer(reinterpret_cast<MediaMuxer *>(nativeObject));
if (muxer == NULL) {
@@ -193,7 +193,7 @@
}
-static void android_media_MediaMuxer_stop(JNIEnv *env, jclass clazz,
+static void android_media_MediaMuxer_stop(JNIEnv *env, jclass /* clazz */,
jlong nativeObject) {
sp<MediaMuxer> muxer(reinterpret_cast<MediaMuxer *>(nativeObject));
if (muxer == NULL) {
@@ -212,7 +212,7 @@
}
static void android_media_MediaMuxer_native_release(
- JNIEnv *env, jclass clazz, jlong nativeObject) {
+ JNIEnv* /* env */, jclass clazz, jlong nativeObject) {
sp<MediaMuxer> muxer(reinterpret_cast<MediaMuxer *>(nativeObject));
if (muxer != NULL) {
muxer->decStrong(clazz);
diff --git a/media/jni/android_media_MediaProfiles.cpp b/media/jni/android_media_MediaProfiles.cpp
index 007fc14..ca9db91 100644
--- a/media/jni/android_media_MediaProfiles.cpp
+++ b/media/jni/android_media_MediaProfiles.cpp
@@ -34,7 +34,7 @@
// This function is called from a static block in MediaProfiles.java class,
// which won't run until the first time an instance of this class is used.
static void
-android_media_MediaProfiles_native_init(JNIEnv *env)
+android_media_MediaProfiles_native_init(JNIEnv* /* env */)
{
ALOGV("native_init");
Mutex::Autolock lock(sLock);
@@ -45,14 +45,14 @@
}
static jint
-android_media_MediaProfiles_native_get_num_file_formats(JNIEnv *env, jobject thiz)
+android_media_MediaProfiles_native_get_num_file_formats(JNIEnv* /* env */, jobject /* thiz */)
{
ALOGV("native_get_num_file_formats");
return (jint) sProfiles->getOutputFileFormats().size();
}
static jint
-android_media_MediaProfiles_native_get_file_format(JNIEnv *env, jobject thiz, jint index)
+android_media_MediaProfiles_native_get_file_format(JNIEnv *env, jobject /* thiz */, jint index)
{
ALOGV("native_get_file_format: %d", index);
Vector<output_format> formats = sProfiles->getOutputFileFormats();
@@ -65,14 +65,15 @@
}
static jint
-android_media_MediaProfiles_native_get_num_video_encoders(JNIEnv *env, jobject thiz)
+android_media_MediaProfiles_native_get_num_video_encoders(JNIEnv* /* env */, jobject /* thiz */)
{
ALOGV("native_get_num_video_encoders");
return sProfiles->getVideoEncoders().size();
}
static jobject
-android_media_MediaProfiles_native_get_video_encoder_cap(JNIEnv *env, jobject thiz, jint index)
+android_media_MediaProfiles_native_get_video_encoder_cap(JNIEnv *env, jobject /* thiz */,
+ jint index)
{
ALOGV("native_get_video_encoder_cap: %d", index);
Vector<video_encoder> encoders = sProfiles->getVideoEncoders();
@@ -116,14 +117,15 @@
}
static jint
-android_media_MediaProfiles_native_get_num_audio_encoders(JNIEnv *env, jobject thiz)
+android_media_MediaProfiles_native_get_num_audio_encoders(JNIEnv* /* env */, jobject /* thiz */)
{
ALOGV("native_get_num_audio_encoders");
return (jint) sProfiles->getAudioEncoders().size();
}
static jobject
-android_media_MediaProfiles_native_get_audio_encoder_cap(JNIEnv *env, jobject thiz, jint index)
+android_media_MediaProfiles_native_get_audio_encoder_cap(JNIEnv *env, jobject /* thiz */,
+ jint index)
{
ALOGV("native_get_audio_encoder_cap: %d", index);
Vector<audio_encoder> encoders = sProfiles->getAudioEncoders();
@@ -172,7 +174,8 @@
}
static jobject
-android_media_MediaProfiles_native_get_camcorder_profile(JNIEnv *env, jobject thiz, jint id, jint quality)
+android_media_MediaProfiles_native_get_camcorder_profile(JNIEnv *env, jobject /* thiz */, jint id,
+ jint quality)
{
ALOGV("native_get_camcorder_profile: %d %d", id, quality);
if (!isCamcorderQualityKnown(quality)) {
@@ -221,7 +224,8 @@
}
static jboolean
-android_media_MediaProfiles_native_has_camcorder_profile(JNIEnv *env, jobject thiz, jint id, jint quality)
+android_media_MediaProfiles_native_has_camcorder_profile(JNIEnv* /* env */, jobject /* thiz */,
+ jint id, jint quality)
{
ALOGV("native_has_camcorder_profile: %d %d", id, quality);
if (!isCamcorderQualityKnown(quality)) {
@@ -233,14 +237,15 @@
}
static jint
-android_media_MediaProfiles_native_get_num_video_decoders(JNIEnv *env, jobject thiz)
+android_media_MediaProfiles_native_get_num_video_decoders(JNIEnv* /* env */, jobject /* thiz */)
{
ALOGV("native_get_num_video_decoders");
return (jint) sProfiles->getVideoDecoders().size();
}
static jint
-android_media_MediaProfiles_native_get_video_decoder_type(JNIEnv *env, jobject thiz, jint index)
+android_media_MediaProfiles_native_get_video_decoder_type(JNIEnv *env, jobject /* thiz */,
+ jint index)
{
ALOGV("native_get_video_decoder_type: %d", index);
Vector<video_decoder> decoders = sProfiles->getVideoDecoders();
@@ -254,14 +259,15 @@
}
static jint
-android_media_MediaProfiles_native_get_num_audio_decoders(JNIEnv *env, jobject thiz)
+android_media_MediaProfiles_native_get_num_audio_decoders(JNIEnv* /* env */, jobject /* thiz */)
{
ALOGV("native_get_num_audio_decoders");
return (jint) sProfiles->getAudioDecoders().size();
}
static jint
-android_media_MediaProfiles_native_get_audio_decoder_type(JNIEnv *env, jobject thiz, jint index)
+android_media_MediaProfiles_native_get_audio_decoder_type(JNIEnv *env, jobject /* thiz */,
+ jint index)
{
ALOGV("native_get_audio_decoder_type: %d", index);
Vector<audio_decoder> decoders = sProfiles->getAudioDecoders();
@@ -275,14 +281,17 @@
}
static jint
-android_media_MediaProfiles_native_get_num_image_encoding_quality_levels(JNIEnv *env, jobject thiz, jint cameraId)
+android_media_MediaProfiles_native_get_num_image_encoding_quality_levels(JNIEnv* /* env */,
+ jobject /* thiz */,
+ jint cameraId)
{
ALOGV("native_get_num_image_encoding_quality_levels");
return (jint) sProfiles->getImageEncodingQualityLevels(cameraId).size();
}
static jint
-android_media_MediaProfiles_native_get_image_encoding_quality_level(JNIEnv *env, jobject thiz, jint cameraId, jint index)
+android_media_MediaProfiles_native_get_image_encoding_quality_level(JNIEnv *env, jobject /* thiz */,
+ jint cameraId, jint index)
{
ALOGV("native_get_image_encoding_quality_level");
Vector<int> levels = sProfiles->getImageEncodingQualityLevels(cameraId);
diff --git a/media/jni/android_media_MediaScanner.cpp b/media/jni/android_media_MediaScanner.cpp
index 321c2e3..1a9384e 100644
--- a/media/jni/android_media_MediaScanner.cpp
+++ b/media/jni/android_media_MediaScanner.cpp
@@ -360,7 +360,6 @@
env->SetByteArrayRegion(array, 0, mediaAlbumArt->size(), data);
}
-done:
free(mediaAlbumArt);
// if NewByteArray() returned NULL, an out-of-memory
// exception will have been raised. I just want to
diff --git a/media/jni/android_media_ResampleInputStream.cpp b/media/jni/android_media_ResampleInputStream.cpp
index d5a4a17..1549a30 100644
--- a/media/jni/android_media_ResampleInputStream.cpp
+++ b/media/jni/android_media_ResampleInputStream.cpp
@@ -73,7 +73,7 @@
static const int BUF_SIZE = 2048;
-static void android_media_ResampleInputStream_fir21(JNIEnv *env, jclass clazz,
+static void android_media_ResampleInputStream_fir21(JNIEnv *env, jclass /* clazz */,
jbyteArray jIn, jint jInOffset,
jbyteArray jOut, jint jOutOffset,
jint jNpoints) {
diff --git a/media/jni/android_media_Utils.cpp b/media/jni/android_media_Utils.cpp
index 54c5e9b..ea33a2f 100644
--- a/media/jni/android_media_Utils.cpp
+++ b/media/jni/android_media_Utils.cpp
@@ -136,8 +136,7 @@
jstring keyObj = env->NewStringUTF(key);
jobject valueObj = makeIntegerObject(env, value);
- jobject res = env->CallObjectMethod(
- hashMapObj, hashMapPutID, keyObj, valueObj);
+ env->CallObjectMethod(hashMapObj, hashMapPutID, keyObj, valueObj);
env->DeleteLocalRef(valueObj); valueObj = NULL;
env->DeleteLocalRef(keyObj); keyObj = NULL;
@@ -266,8 +265,7 @@
if (valueObj != NULL) {
jstring keyObj = env->NewStringUTF(key);
- jobject res = env->CallObjectMethod(
- hashMap, hashMapPutID, keyObj, valueObj);
+ env->CallObjectMethod(hashMap, hashMapPutID, keyObj, valueObj);
env->DeleteLocalRef(keyObj); keyObj = NULL;
env->DeleteLocalRef(valueObj); valueObj = NULL;
diff --git a/media/jni/android_mtp_MtpDatabase.cpp b/media/jni/android_mtp_MtpDatabase.cpp
index 62b4a36..9dda346 100644
--- a/media/jni/android_mtp_MtpDatabase.cpp
+++ b/media/jni/android_mtp_MtpDatabase.cpp
@@ -762,7 +762,7 @@
return result;
}
-static void foreachentry(ExifEntry *entry, void * /*user*/) {
+static void foreachentry(ExifEntry *entry, void* /* user */) {
char buf[1024];
ALOGI("entry %x, format %d, size %d: %s",
entry->tag, entry->format, entry->size, exif_entry_get_value(entry, buf, sizeof(buf)));
@@ -780,7 +780,6 @@
MtpResponseCode MyMtpDatabase::getObjectInfo(MtpObjectHandle handle,
MtpObjectInfo& info) {
- char date[20];
MtpString path;
int64_t length;
MtpObjectFormat format;
@@ -808,9 +807,11 @@
info.mDateModified = longValues[1];
env->ReleaseLongArrayElements(mLongBuffer, longValues, 0);
-// info.mAssociationType = (format == MTP_FORMAT_ASSOCIATION ?
-// MTP_ASSOCIATION_TYPE_GENERIC_FOLDER :
-// MTP_ASSOCIATION_TYPE_UNDEFINED);
+ if ((false)) {
+ info.mAssociationType = (format == MTP_FORMAT_ASSOCIATION ?
+ MTP_ASSOCIATION_TYPE_GENERIC_FOLDER :
+ MTP_ASSOCIATION_TYPE_UNDEFINED);
+ }
info.mAssociationType = MTP_ASSOCIATION_TYPE_UNDEFINED;
jchar* str = env->GetCharArrayElements(mStringBuffer, 0);
@@ -823,7 +824,9 @@
ExifData *exifdata = exif_data_new_from_file(path);
if (exifdata) {
- //exif_data_foreach_content(exifdata, foreachcontent, NULL);
+ if ((false)) {
+ exif_data_foreach_content(exifdata, foreachcontent, NULL);
+ }
// XXX get this from exif, or parse jpeg header instead?
ExifEntry *w = exif_content_get_entry(
diff --git a/media/jni/android_mtp_MtpDevice.cpp b/media/jni/android_mtp_MtpDevice.cpp
index 8e013a0..fb15770 100644
--- a/media/jni/android_mtp_MtpDevice.cpp
+++ b/media/jni/android_mtp_MtpDevice.cpp
@@ -91,14 +91,6 @@
return (MtpDevice*)env->GetLongField(javaDevice, field_context);
}
-static void checkAndClearExceptionFromCallback(JNIEnv* env, const char* methodName) {
- if (env->ExceptionCheck()) {
- ALOGE("An exception was thrown by callback '%s'.", methodName);
- LOGE_EX(env);
- env->ExceptionClear();
- }
-}
-
// ----------------------------------------------------------------------------
static jboolean
diff --git a/media/jni/audioeffect/Android.mk b/media/jni/audioeffect/Android.mk
index 3b1fb19..5c22c9b 100644
--- a/media/jni/audioeffect/Android.mk
+++ b/media/jni/audioeffect/Android.mk
@@ -2,20 +2,22 @@
include $(CLEAR_VARS)
LOCAL_SRC_FILES:= \
- android_media_AudioEffect.cpp \
- android_media_Visualizer.cpp
+ android_media_AudioEffect.cpp \
+ android_media_Visualizer.cpp
LOCAL_SHARED_LIBRARIES := \
- liblog \
- libcutils \
- libutils \
- libandroid_runtime \
- libnativehelper \
- libmedia
+ liblog \
+ libcutils \
+ libutils \
+ libandroid_runtime \
+ libnativehelper \
+ libmedia
LOCAL_C_INCLUDES := \
- $(call include-path-for, audio-effects)
+ $(call include-path-for, audio-effects)
LOCAL_MODULE:= libaudioeffect_jni
+LOCAL_CFLAGS += -Wall -Werror -Wunused -Wunreachable-code
+
include $(BUILD_SHARED_LIBRARY)
diff --git a/media/jni/audioeffect/android_media_Visualizer.cpp b/media/jni/audioeffect/android_media_Visualizer.cpp
index 8463d94..9183ad2 100644
--- a/media/jni/audioeffect/android_media_Visualizer.cpp
+++ b/media/jni/audioeffect/android_media_Visualizer.cpp
@@ -162,10 +162,6 @@
uint8_t *fft,
uint32_t samplingrate) {
- int arg1 = 0;
- int arg2 = 0;
- size_t size;
-
visualizer_callback_cookie *callbackInfo = (visualizer_callback_cookie *)user;
JNIEnv *env = AndroidRuntime::getJNIEnv();
@@ -486,7 +482,7 @@
}
static jintArray
-android_media_visualizer_native_getCaptureSizeRange(JNIEnv *env, jobject thiz)
+android_media_visualizer_native_getCaptureSizeRange(JNIEnv *env, jobject /* thiz */)
{
jintArray jRange = env->NewIntArray(2);
jint *nRange = env->GetIntArrayElements(jRange, NULL);
@@ -498,7 +494,7 @@
}
static jint
-android_media_visualizer_native_getMaxCaptureRate(JNIEnv *env, jobject thiz)
+android_media_visualizer_native_getMaxCaptureRate(JNIEnv* /* env */, jobject /* thiz */)
{
return (jint) Visualizer::getMaxCaptureRate();
}
diff --git a/media/jni/soundpool/Android.mk b/media/jni/soundpool/Android.mk
index ed8d7c1..3382512 100644
--- a/media/jni/soundpool/Android.mk
+++ b/media/jni/soundpool/Android.mk
@@ -2,16 +2,18 @@
include $(CLEAR_VARS)
LOCAL_SRC_FILES:= \
- android_media_SoundPool_SoundPoolImpl.cpp
+ android_media_SoundPool_SoundPoolImpl.cpp
LOCAL_SHARED_LIBRARIES := \
- liblog \
- libcutils \
- libutils \
- libandroid_runtime \
- libnativehelper \
- libmedia
+ liblog \
+ libcutils \
+ libutils \
+ libandroid_runtime \
+ libnativehelper \
+ libmedia
LOCAL_MODULE:= libsoundpool
+LOCAL_CFLAGS += -Wall -Werror -Wunused -Wunreachable-code
+
include $(BUILD_SHARED_LIBRARY)
diff --git a/media/jni/soundpool/android_media_SoundPool_SoundPoolImpl.cpp b/media/jni/soundpool/android_media_SoundPool_SoundPoolImpl.cpp
index 89b2893..ce20e52 100644
--- a/media/jni/soundpool/android_media_SoundPool_SoundPoolImpl.cpp
+++ b/media/jni/soundpool/android_media_SoundPool_SoundPoolImpl.cpp
@@ -312,7 +312,7 @@
static const char* const kClassPathName = "android/media/SoundPool$SoundPoolImpl";
-jint JNI_OnLoad(JavaVM* vm, void* reserved)
+jint JNI_OnLoad(JavaVM* vm, void* /* reserved */)
{
JNIEnv* env = NULL;
jint result = -1;
diff --git a/media/mca/filterfw/Android.mk b/media/mca/filterfw/Android.mk
index 2a9448d..a5b4b27 100644
--- a/media/mca/filterfw/Android.mk
+++ b/media/mca/filterfw/Android.mk
@@ -22,6 +22,7 @@
# Build main libfilterfw
include $(CLEAR_VARS)
+LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
LOCAL_MODULE := libfilterfw
@@ -30,7 +31,7 @@
LOCAL_WHOLE_STATIC_LIBRARIES := libfilterfw_jni \
libfilterfw_native
-LOCAL_SHARED_LIBRARIES := libstlport \
+LOCAL_SHARED_LIBRARIES := \
libGLESv2 \
libEGL \
libgui \
@@ -48,4 +49,5 @@
# part of a system image.
LOCAL_PRELINK_MODULE := false
+include external/stlport/libstlport.mk
include $(BUILD_SHARED_LIBRARY)
diff --git a/media/mca/filterfw/java/android/filterfw/geometry/Point.java b/media/mca/filterfw/java/android/filterfw/geometry/Point.java
index 8207c72c..4682a0d 100644
--- a/media/mca/filterfw/java/android/filterfw/geometry/Point.java
+++ b/media/mca/filterfw/java/android/filterfw/geometry/Point.java
@@ -70,7 +70,7 @@
}
public float length() {
- return (float)Math.sqrt(x*x + y*y);
+ return (float)Math.hypot(x, y);
}
public float distanceTo(Point p) {
diff --git a/media/mca/filterfw/jni/Android.mk b/media/mca/filterfw/jni/Android.mk
index 5aa5af1..67337e0 100644
--- a/media/mca/filterfw/jni/Android.mk
+++ b/media/mca/filterfw/jni/Android.mk
@@ -38,8 +38,8 @@
# Also need the JNI headers.
LOCAL_C_INCLUDES += \
- $(JNI_H_INCLUDE) \
- $(LOCAL_PATH)/..
+ $(JNI_H_INCLUDE) \
+ $(LOCAL_PATH)/..
# Don't prelink this library. For more efficient code, you may want
# to add this library to the prelink map and set this to true. However,
@@ -47,5 +47,7 @@
# part of a system image.
LOCAL_PRELINK_MODULE := false
+LOCAL_CFLAGS += -Wall -Werror -Wunused -Wunreachable-code
+
include $(BUILD_STATIC_LIBRARY)
diff --git a/media/mca/filterfw/jni/jni_gl_environment.cpp b/media/mca/filterfw/jni/jni_gl_environment.cpp
index 6da7b7c..5f00739 100644
--- a/media/mca/filterfw/jni/jni_gl_environment.cpp
+++ b/media/mca/filterfw/jni/jni_gl_environment.cpp
@@ -20,8 +20,8 @@
#include "jni/jni_gl_environment.h"
#include "jni/jni_util.h"
-#include <media/mediarecorder.h>
#include "native/core/gl_env.h"
+#include <media/mediarecorder.h>
#include <gui/IGraphicBufferProducer.h>
#include <gui/Surface.h>
@@ -92,8 +92,8 @@
return gl_env ? ToJBool(gl_env->IsContextActive()) : JNI_FALSE;
}
-jboolean Java_android_filterfw_core_GLEnvironment_nativeIsAnyContextActive(JNIEnv* env,
- jclass clazz) {
+jboolean Java_android_filterfw_core_GLEnvironment_nativeIsAnyContextActive(JNIEnv* /* env */,
+ jclass /* clazz */) {
return ToJBool(GLEnv::IsAnyContextActive());
}
diff --git a/media/mca/filterfw/jni/jni_init.cpp b/media/mca/filterfw/jni/jni_init.cpp
index 3b131f1..956a5a5 100644
--- a/media/mca/filterfw/jni/jni_init.cpp
+++ b/media/mca/filterfw/jni/jni_init.cpp
@@ -27,7 +27,7 @@
JavaVM* g_current_java_vm_ = NULL;
-jint JNI_OnLoad(JavaVM* vm, void* reserved) {
+jint JNI_OnLoad(JavaVM* vm, void* /* reserved */) {
// Set the current vm pointer
g_current_java_vm_ = vm;
diff --git a/media/mca/filterfw/native/Android.mk b/media/mca/filterfw/native/Android.mk
index 46ee283..7c4703f 100644
--- a/media/mca/filterfw/native/Android.mk
+++ b/media/mca/filterfw/native/Android.mk
@@ -39,6 +39,8 @@
# gcc should always be placed at the end.
LOCAL_EXPORT_LDLIBS := -llog -lgcc
+LOCAL_CFLAGS += -Wall -Werror -Wunused -Wunreachable-code
+
# TODO: Build a shared library as well?
include $(BUILD_STATIC_LIBRARY)
diff --git a/media/mca/filterfw/native/core/shader_program.cpp b/media/mca/filterfw/native/core/shader_program.cpp
index d92eb31..002327b 100644
--- a/media/mca/filterfw/native/core/shader_program.cpp
+++ b/media/mca/filterfw/native/core/shader_program.cpp
@@ -318,15 +318,15 @@
ALOGE("Problem compiling shader! Source:");
ALOGE("%s", source);
std::string src(source);
- unsigned int cur_pos = 0;
- unsigned int next_pos = 0;
- int line_number = 1;
+ size_t cur_pos = 0;
+ size_t next_pos = 0;
+ size_t line_number = 1;
while ( (next_pos = src.find_first_of('\n', cur_pos)) != std::string::npos) {
ALOGE("%03d : %s", line_number, src.substr(cur_pos, next_pos-cur_pos).c_str());
cur_pos = next_pos + 1;
line_number++;
}
- ALOGE("%03d : %s", line_number, src.substr(cur_pos, next_pos-cur_pos).c_str());
+ ALOGE("%03zu : %s", line_number, src.substr(cur_pos, next_pos-cur_pos).c_str());
GLint log_length = 0;
glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &log_length);
diff --git a/media/mca/filterfw/native/core/vertex_frame.cpp b/media/mca/filterfw/native/core/vertex_frame.cpp
index 822573f..9fb9eaa 100644
--- a/media/mca/filterfw/native/core/vertex_frame.cpp
+++ b/media/mca/filterfw/native/core/vertex_frame.cpp
@@ -25,10 +25,6 @@
namespace android {
namespace filterfw {
-// GL Extensions that are dynamically looked up at runtime
-static PFNGLMAPBUFFEROESPROC GLMapBufferOES = NULL;
-static PFNGLUNMAPBUFFEROESPROC GLUnmapBufferOES = NULL;
-
VertexFrame::VertexFrame(int size)
: vbo_(0),
size_(size) {
diff --git a/media/mca/filterpacks/Android.mk b/media/mca/filterpacks/Android.mk
index 6e54f60..d030749 100644
--- a/media/mca/filterpacks/Android.mk
+++ b/media/mca/filterpacks/Android.mk
@@ -28,6 +28,8 @@
LOCAL_CFLAGS := -DANDROID
+LOCAL_CFLAGS += -Wall -Werror -Wunused -Wunreachable-code
+
include external/stlport/libstlport.mk
include $(BUILD_STATIC_LIBRARY)
@@ -50,4 +52,6 @@
LOCAL_PRELINK_MODULE := false
+LOCAL_CFLAGS += -Wall -Werror -Wunused -Wunreachable-code
+
include $(BUILD_SHARED_LIBRARY)
diff --git a/media/mca/filterpacks/native/imageproc/invert.c b/media/mca/filterpacks/native/imageproc/invert.c
index 5938aac..f5f9e27 100644
--- a/media/mca/filterpacks/native/imageproc/invert.c
+++ b/media/mca/filterpacks/native/imageproc/invert.c
@@ -16,12 +16,14 @@
#include <android/log.h>
+#define ATTRIBUTE_UNUSED __attribute__((unused))
+
int invert_process(const char** inputs,
const int* input_sizes,
int input_count,
char* output,
int output_size,
- void* user_data) {
+ void* user_data ATTRIBUTE_UNUSED) {
// Make sure we have exactly one input
if (input_count != 1)
return 0;
diff --git a/media/mca/filterpacks/native/imageproc/to_rgba.c b/media/mca/filterpacks/native/imageproc/to_rgba.c
index bf4db2a..80094c0 100644
--- a/media/mca/filterpacks/native/imageproc/to_rgba.c
+++ b/media/mca/filterpacks/native/imageproc/to_rgba.c
@@ -16,12 +16,14 @@
#include <stdlib.h>
+#define ATTRIBUTE_UNUSED __attribute__((unused))
+
int gray_to_rgb_process(const char** inputs,
const int* input_sizes,
int input_count,
char* output,
int output_size,
- void* user_data) {
+ void* user_data ATTRIBUTE_UNUSED) {
// Make sure we have exactly one input
if (input_count != 1)
return 0;
@@ -52,7 +54,7 @@
int input_count,
char* output,
int output_size,
- void* user_data) {
+ void* user_data ATTRIBUTE_UNUSED) {
// Make sure we have exactly one input
if (input_count != 1)
return 0;
@@ -84,7 +86,7 @@
int input_count,
char* output,
int output_size,
- void* user_data) {
+ void* user_data ATTRIBUTE_UNUSED) {
// Make sure we have exactly one input
if (input_count != 1)
return 0;
@@ -116,7 +118,7 @@
int input_count,
char* output,
int output_size,
- void* user_data) {
+ void* user_data ATTRIBUTE_UNUSED) {
// Make sure we have exactly one input
if (input_count != 1)
return 0;
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/camera/CameraFunctionalTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/camera/CameraFunctionalTest.java
index e6f0aaf..d12ef2e 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/camera/CameraFunctionalTest.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/camera/CameraFunctionalTest.java
@@ -37,7 +37,6 @@
import android.os.Looper;
import android.test.ActivityInstrumentationTestCase2;
import android.test.suitebuilder.annotation.LargeTest;
-import android.util.FloatMath;
import android.util.Log;
import android.view.SurfaceHolder;
import com.android.mediaframeworktest.CameraStressTestRunner;
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/camera/CameraPairwiseTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/camera/CameraPairwiseTest.java
index 61b708a..8f67598 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/camera/CameraPairwiseTest.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/camera/CameraPairwiseTest.java
@@ -24,7 +24,6 @@
import android.os.Looper;
import android.test.ActivityInstrumentationTestCase2;
import android.test.suitebuilder.annotation.LargeTest;
-import android.util.FloatMath;
import android.util.Log;
import android.view.SurfaceHolder;
diff --git a/native/android/Android.mk b/native/android/Android.mk
index cda38e0..b3a74a8 100644
--- a/native/android/Android.mk
+++ b/native/android/Android.mk
@@ -34,6 +34,8 @@
frameworks/base/native/include \
frameworks/base/core/jni/android
-LOCAL_MODULE:= libandroid
+LOCAL_MODULE := libandroid
+
+LOCAL_CFLAGS += -Wall -Werror -Wunused -Wunreachable-code
include $(BUILD_SHARED_LIBRARY)
diff --git a/native/graphics/jni/Android.mk b/native/graphics/jni/Android.mk
index 3154030..88954f0 100644
--- a/native/graphics/jni/Android.mk
+++ b/native/graphics/jni/Android.mk
@@ -6,27 +6,29 @@
# setup for skia optimizations
#
ifneq ($(ARCH_ARM_HAVE_VFP),true)
- LOCAL_CFLAGS += -DSK_SOFTWARE_FLOAT
+ LOCAL_CFLAGS += -DSK_SOFTWARE_FLOAT
endif
ifeq ($(ARCH_ARM_HAVE_NEON),true)
- LOCAL_CFLAGS += -D__ARM_HAVE_NEON
+ LOCAL_CFLAGS += -D__ARM_HAVE_NEON
endif
# our source files
#
LOCAL_SRC_FILES:= \
- bitmap.cpp
+ bitmap.cpp
LOCAL_SHARED_LIBRARIES := \
libandroid_runtime \
libskia
LOCAL_C_INCLUDES += \
- frameworks/base/native/include \
- frameworks/base/core/jni/android/graphics
+ frameworks/base/native/include \
+ frameworks/base/core/jni/android/graphics
LOCAL_MODULE:= libjnigraphics
+LOCAL_CFLAGS += -Wall -Werror -Wunused -Wunreachable-code
+
include $(BUILD_SHARED_LIBRARY)
diff --git a/native/graphics/jni/bitmap.cpp b/native/graphics/jni/bitmap.cpp
index df0751d..ea32edc 100644
--- a/native/graphics/jni/bitmap.cpp
+++ b/native/graphics/jni/bitmap.cpp
@@ -15,7 +15,11 @@
*/
#include <android/bitmap.h>
+
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wunused-parameter"
#include <GraphicsJNI.h>
+#pragma GCC diagnostic pop
int AndroidBitmap_getInfo(JNIEnv* env, jobject jbitmap,
AndroidBitmapInfo* info) {
diff --git a/packages/BackupRestoreConfirmation/res/values-es/strings.xml b/packages/BackupRestoreConfirmation/res/values-es/strings.xml
index 01f7cf7..ac0836d 100644
--- a/packages/BackupRestoreConfirmation/res/values-es/strings.xml
+++ b/packages/BackupRestoreConfirmation/res/values-es/strings.xml
@@ -25,11 +25,11 @@
<string name="allow_restore_button_label" msgid="3081286752277127827">"Restaurar mis datos"</string>
<string name="deny_restore_button_label" msgid="1724367334453104378">"No restaurar"</string>
<string name="current_password_text" msgid="8268189555578298067">"Introduce a continuación la contraseña actual de copia de seguridad:"</string>
- <string name="device_encryption_restore_text" msgid="1570864916855208992">"Introduce a continuación la contraseña de encriptación del dispositivo."</string>
- <string name="device_encryption_backup_text" msgid="5866590762672844664">"Introduce a continuación la contraseña de encriptación del dispositivo. Esta contraseña se usará también para encriptar el archivo de copia de seguridad."</string>
+ <string name="device_encryption_restore_text" msgid="1570864916855208992">"Introduce a continuación la contraseña de cifrado del dispositivo."</string>
+ <string name="device_encryption_backup_text" msgid="5866590762672844664">"Introduce a continuación la contraseña de cifrado del dispositivo. Esta contraseña se usará también para cifrar el archivo de copia de seguridad."</string>
<string name="backup_enc_password_text" msgid="4981585714795233099">"Introduce la contraseña que quieras usar para cifrar los datos de la copia de seguridad completa. Si dejas este campo en blanco, se usará tu contraseña de copia de seguridad actual:"</string>
<string name="backup_enc_password_optional" msgid="1350137345907579306">"Si quieres cifrar los datos de la copia de seguridad completa, introduce la contraseña a continuación:"</string>
- <string name="backup_enc_password_required" msgid="7889652203371654149">"Tu dispositivo está encriptado, por lo que debes encriptar tu copia de seguridad. Introduce una contraseña a continuación:"</string>
+ <string name="backup_enc_password_required" msgid="7889652203371654149">"Tu dispositivo está cifrado, por lo que debes cifrar tu copia de seguridad. Introduce una contraseña a continuación:"</string>
<string name="restore_enc_password_text" msgid="6140898525580710823">"Si los datos de restauración están cifrados, introduce la contraseña a continuación:"</string>
<string name="toast_backup_started" msgid="550354281452756121">"Iniciando copia de seguridad..."</string>
<string name="toast_backup_ended" msgid="3818080769548726424">"Copia de seguridad finalizada"</string>
diff --git a/packages/BackupRestoreConfirmation/res/values-hi/strings.xml b/packages/BackupRestoreConfirmation/res/values-hi/strings.xml
index 71a319f..2578e8f 100644
--- a/packages/BackupRestoreConfirmation/res/values-hi/strings.xml
+++ b/packages/BackupRestoreConfirmation/res/values-hi/strings.xml
@@ -21,15 +21,15 @@
<string name="backup_confirm_text" msgid="1878021282758896593">"कनेक्ट किए गए डेस्कटॉप कंप्यूटर से सभी डेटा के संपूर्ण सुरक्षा का अनुरोध किया गया है. क्या आप इसकी अनुमति देना चाहते हैं?\n\nयदि आपने स्वयं बैकअप का अनुरोध नहीं किया है, तो प्रक्रिया जारी रखने की अनुमति न दें."</string>
<string name="allow_backup_button_label" msgid="4217228747769644068">"मेरे डेटा का बैकअप लें"</string>
<string name="deny_backup_button_label" msgid="6009119115581097708">"बैकअप न लें"</string>
- <string name="restore_confirm_text" msgid="7499866728030461776">"कनेक्ट किए गए डेस्कटॉप कंप्यूटर से सभी डेटा की पूर्ण पुनर्स्थापना का अनुरोध किया गया है. क्या आप इसकी अनुमति देना चाहते हैं?\n\nयदि आपने स्वयं पुनर्प्राप्ति का अनुरोध नहीं किया है, तो प्रक्रिया जारी रखने की अनुमति न दें. इससे वर्तमान में आपके उपकरण पर मौजूद डेटा बदल जाएगा!"</string>
+ <string name="restore_confirm_text" msgid="7499866728030461776">"कनेक्ट किए गए डेस्कटॉप कंप्यूटर से सभी डेटा की पूर्ण पुनर्स्थापना का अनुरोध किया गया है. क्या आप इसकी अनुमति देना चाहते हैं?\n\nयदि आपने स्वयं पुनर्प्राप्ति का अनुरोध नहीं किया है, तो प्रक्रिया जारी रखने की अनुमति न दें. इससे वर्तमान में आपके डिवाइस पर मौजूद डेटा बदल जाएगा!"</string>
<string name="allow_restore_button_label" msgid="3081286752277127827">"मेरा डेटा पुनर्स्थापित करें"</string>
<string name="deny_restore_button_label" msgid="1724367334453104378">"पुनर्स्थापित न करें"</string>
<string name="current_password_text" msgid="8268189555578298067">"कृपया नीचे अपना वर्तमान सुरक्षित करने का पासवर्ड डालें:"</string>
- <string name="device_encryption_restore_text" msgid="1570864916855208992">"कृपया नीचे अपना उपकरण एन्क्रिप्शन पासवर्ड डालें."</string>
- <string name="device_encryption_backup_text" msgid="5866590762672844664">"कृपया अपना उपकरण सुरक्षित तरीका पासवर्ड नीचे दर्ज करें. बैकअप संग्रहण को एन्क्रिप्ट करने के लिए भी इसका उपयोग किया जाएगा."</string>
+ <string name="device_encryption_restore_text" msgid="1570864916855208992">"कृपया नीचे अपना डिवाइस एन्क्रिप्शन पासवर्ड डालें."</string>
+ <string name="device_encryption_backup_text" msgid="5866590762672844664">"कृपया अपना डिवाइस सुरक्षित तरीका पासवर्ड नीचे दर्ज करें. बैकअप मेमोरी को एन्क्रिप्ट करने के लिए भी इसका उपयोग किया जाएगा."</string>
<string name="backup_enc_password_text" msgid="4981585714795233099">"कृपया संपूर्ण सुरक्षित डेटा को एन्क्रिप्ट करने में उपयोग के लिए पासवर्ड डालें. यदि यह खाली छोड़ दिया जाता है, तो आपके वर्तमान बैकअप पासवर्ड का उपयोग किया जाएगा:"</string>
<string name="backup_enc_password_optional" msgid="1350137345907579306">"यदि आप संपूर्ण सुरक्षित डेटा को एन्क्रिप्ट करना चाहते हैं, तो नीचे पासवर्ड डालें:"</string>
- <string name="backup_enc_password_required" msgid="7889652203371654149">"चूंकि आपका उपकरण एन्क्रिप्ट किया हुआ है, इसलिए आपको अपने बैकअप को एन्क्रिप्ट करना आवश्यक है. कृपया नीचे पासवर्ड डालें:"</string>
+ <string name="backup_enc_password_required" msgid="7889652203371654149">"चूंकि आपका डिवाइस एन्क्रिप्ट किया हुआ है, इसलिए आपको अपने बैकअप को एन्क्रिप्ट करना आवश्यक है. कृपया नीचे पासवर्ड डालें:"</string>
<string name="restore_enc_password_text" msgid="6140898525580710823">"यदि पुनर्स्थापित डेटा को एन्क्रिप्ट किया गया है, तो कृपया नीचे पासवर्ड डालें:"</string>
<string name="toast_backup_started" msgid="550354281452756121">"सुरक्षित करना शुरु हो रहा है..."</string>
<string name="toast_backup_ended" msgid="3818080769548726424">"सुरक्षित करना पूर्ण"</string>
diff --git a/packages/BackupRestoreConfirmation/res/values-kk-rKZ/strings.xml b/packages/BackupRestoreConfirmation/res/values-kk-rKZ/strings.xml
index 6a36b9e..38d7172 100644
--- a/packages/BackupRestoreConfirmation/res/values-kk-rKZ/strings.xml
+++ b/packages/BackupRestoreConfirmation/res/values-kk-rKZ/strings.xml
@@ -29,8 +29,7 @@
<string name="device_encryption_backup_text" msgid="5866590762672844664">"Құрылғыңыздың кодтық кілтсөзін енгізіңіз. Ол сақтық көшірме мұрағатын кодтау үшін де қолданылады."</string>
<string name="backup_enc_password_text" msgid="4981585714795233099">"Деректердің сақтық көшірмесін толығымен шифрлау үшін кілтсөзді енгізіңіз. Егер бұл бос қалдырылса, сіздің қазіргі сақтық көшірме кілтсөзіңіз қолданылады:"</string>
<string name="backup_enc_password_optional" msgid="1350137345907579306">"Деректердің сақтық көшірмесін толығымен шифрлауды қаласаңыз, кілтсөзді енгізіңіз:"</string>
- <!-- no translation found for backup_enc_password_required (7889652203371654149) -->
- <skip />
+ <string name="backup_enc_password_required" msgid="7889652203371654149">"Құрылғыңыз шифрланғандықтан, сақтық көшірмені шифрлау қажет. Төменде құпия сөзді енгізіңіз:"</string>
<string name="restore_enc_password_text" msgid="6140898525580710823">"Қалпына келтіру деректері кодталса, кілтсөзді енгізіңіз:"</string>
<string name="toast_backup_started" msgid="550354281452756121">"Сақтық көшірме басталуда..."</string>
<string name="toast_backup_ended" msgid="3818080769548726424">"Қалпына келтіру аяқталды"</string>
diff --git a/packages/BackupRestoreConfirmation/res/values-ky-rKG/strings.xml b/packages/BackupRestoreConfirmation/res/values-ky-rKG/strings.xml
index 3c7b6e7..6333b18 100644
--- a/packages/BackupRestoreConfirmation/res/values-ky-rKG/strings.xml
+++ b/packages/BackupRestoreConfirmation/res/values-ky-rKG/strings.xml
@@ -29,8 +29,7 @@
<string name="device_encryption_backup_text" msgid="5866590762672844664">"Түзмөгүңүздүн шифрлөө сырсөзүн төмөндө киргизиңиз. Ал бэкап архивин шифрлегенге дагы колдонулат."</string>
<string name="backup_enc_password_text" msgid="4981585714795233099">"Эгер сиз толук бэкапты шифрлегиңиз келсе, төмөндө сырсөз киргизиңиз. Эгер ал бош калтырылса, анда учурдагы сырсөз колдонулат:"</string>
<string name="backup_enc_password_optional" msgid="1350137345907579306">"Эгер сиз толук бэкапты шифрлегиңиз келсе, төмөндө сырсөз киргизиңиз:"</string>
- <!-- no translation found for backup_enc_password_required (7889652203371654149) -->
- <skip />
+ <string name="backup_enc_password_required" msgid="7889652203371654149">"Түзмөгүңүз шифрленген болгондуктан, камдооңузду шифрлешиңиз керек. Төмөнгө сырсөз киргизиңиз:"</string>
<string name="restore_enc_password_text" msgid="6140898525580710823">"Эгер калыбына келтирүү берилиштери шифрленген болсо, төмөндө сырсөздү киргизиңиз:"</string>
<string name="toast_backup_started" msgid="550354281452756121">"Бэкап башталды..."</string>
<string name="toast_backup_ended" msgid="3818080769548726424">"Бэкап аяктады"</string>
diff --git a/packages/BackupRestoreConfirmation/res/values-my-rMM/strings.xml b/packages/BackupRestoreConfirmation/res/values-my-rMM/strings.xml
index d499771..6e276ec 100644
--- a/packages/BackupRestoreConfirmation/res/values-my-rMM/strings.xml
+++ b/packages/BackupRestoreConfirmation/res/values-my-rMM/strings.xml
@@ -16,21 +16,21 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="backup_confirm_title" msgid="827563724209303345">"အရံ သိမ်းဆည်းမှု အပြည့်လုပ်ရန်"</string>
+ <string name="backup_confirm_title" msgid="827563724209303345">"အရံ သိမ်းဆည်းမှု အပြည့်လုပ်ရန်"</string>
<string name="restore_confirm_title" msgid="5469365809567486602">"အားလုံးပြန်လည်ရယူရန်"</string>
- <string name="backup_confirm_text" msgid="1878021282758896593">"ချိတ်ဆက်ထားသောကွန်ပြုတာသို့ ဒေတာအားလုံးအား အရန်သိမ်းဆည်းရန် တောင်းခံပါသည်။ သင်ခွင့်ပြုမည်လား။ \n\nအကယ်၍ သင်သည်အရန်သိမ်းဆည်းရန် မတောင်းခံခဲ့ပါက ဤဆောင်ရွက်ချက်အား ရှေ့ဆက်ရန်ခွင့်မပြုပါနှင့်။"</string>
+ <string name="backup_confirm_text" msgid="1878021282758896593">"ချိတ်ဆက်ထားသောကွန်ပြုတာသို့ ဒေတာအားလုံးအား အရန်သိမ်းဆည်းရန် တောင်းခံပါသည်။ သင်ခွင့်ပြုမည်လား။ \n\nအကယ်၍ သင်သည်အရန်သိမ်းဆည်းရန် မတောင်းခံခဲ့ပါက ဤဆောင်ရွက်ချက်အား ရှေ့ဆက်ရန်ခွင့်မပြုပါနှင့်။"</string>
<string name="allow_backup_button_label" msgid="4217228747769644068">"ကျွန်ုပ်၏ဒေတာများကို အရန်ထားခြင်း"</string>
- <string name="deny_backup_button_label" msgid="6009119115581097708">"အရံသိမ်းဆည်းမှု မလုပ်ပါနှင့်"</string>
- <string name="restore_confirm_text" msgid="7499866728030461776">"ချိတ်ဆက်ထားသောကွန်ပြုတာသို့ ဒေတာအားလုံးအား ပြန်လည်ရယူရန် တောင်းခံပါသည်။ သင်ခွင့်ပြုမည်လား။ \n\nအကယ်၍ သင်သည် ပြန်လည်ရယူရန် ဤဆောင်ရွက်ချက်အား ရှေ့ဆက်ရန်ခွင့်မပြုပါနှင့်။ လက်ရှိစက်ထဲ၌ရှိသောဒေတာအား အစားထိုးမည်ဖြစ်သည်။"</string>
+ <string name="deny_backup_button_label" msgid="6009119115581097708">"အရံသိမ်းဆည်းမှု မလုပ်ပါနှင့်"</string>
+ <string name="restore_confirm_text" msgid="7499866728030461776">"ချိတ်ဆက်ထားသောကွန်ပြုတာသို့ ဒေတာအားလုံးအား ပြန်လည်ရယူရန် တောင်းခံပါသည်။ သင်ခွင့်ပြုမည်လား။ \n\nအကယ်၍ သင်သည် ပြန်လည်ရယူရန် ဤဆောင်ရွက်ချက်အား ရှေ့ဆက်ရန်ခွင့်မပြုပါနှင့်။ လက်ရှိစက်ထဲ၌ရှိသောဒေတာအား အစားထိုးမည်ဖြစ်သည်။"</string>
<string name="allow_restore_button_label" msgid="3081286752277127827">"ကျွန်ုပ်၏ဒေတာများကို ပြန်လည်ရယူရန်"</string>
- <string name="deny_restore_button_label" msgid="1724367334453104378">"ပြန်လည်ရယူခြင်းအား မပြုလုပ်ပါနှင့်"</string>
- <string name="current_password_text" msgid="8268189555578298067">"သင့်လက်ရှိ အရံသိမ်းဆည်းမှု လျှို့ဝှက်စကားဝှက်အား ထည့်သွင်းပါ။"</string>
- <string name="device_encryption_restore_text" msgid="1570864916855208992">"သင့်စက်၏ လျှို့ဝှက်အသွင်ပြောင်းခြင်းအတွက်စကားဝှက်ကို ထည့်သွင်းပါ။"</string>
- <string name="device_encryption_backup_text" msgid="5866590762672844664">"သင့်စက်၏လျှို့ဝှက်အသွင်ပြောင်းခြင်းအတွက် လျှို့ဝှက်စကားဝှက်အားထည့်ပါ။ အရံသိမ်းဆည်းမှု သိမ်းဆည်းနေရာတွင်လည်း အသုံးပြုမည်ဖြစ်သည်။"</string>
- <string name="backup_enc_password_text" msgid="4981585714795233099">"ဒေတာအားလုံးအားအရန်သိမ်းဆည်းခြင်းပြီးလျှို့ဝှက်အသွင်ပြောင်းခြင်းအတွက် လျှို့ဝှက်နံပါတ်/စာကိုထည့်ပါ။ အကယ်၍ ကွက်လပ်ထားပါက ယခုသင့်လက်ရှိလျှို့ဝှက်စကားဝှက်အား အသုံးပြုပါမည်။"</string>
- <string name="backup_enc_password_optional" msgid="1350137345907579306">"အကယ်၍ ဒေတာအားလုံးအားအရန်သိမ်းဆည်းခြင်းကို ဝှက်လိုပါက အောက်တွင်လျှို့ဝှက်နံပါတ်/စာကိုထည့်ပါ။"</string>
- <string name="backup_enc_password_required" msgid="7889652203371654149">"သင်၏ ကိရိယာကို လျှို့ဝျက်ကုဒ် သွင်းထားရာ၊ သင်သည် သင်၏ ဘက်အာပ်ကိုပါ လျှို့ဝျက်ကုဒ် သွင်းရန် လိုအပ်သည်။ ကျေးဇူးပြုပြီး အောက်မှာ စကားဝှက်ကို ထည့်သွင်းပါ:"</string>
- <string name="restore_enc_password_text" msgid="6140898525580710823">"အကယ်၍ ပြန်လည်ရယူမည့်ဒေတာမှာလျှို့ဝှက်အသွင်ပြောင်းထားပါက အောက်တွင်စကားဝှက်ကိုထည့်ပါ-"</string>
+ <string name="deny_restore_button_label" msgid="1724367334453104378">"ပြန်လည်ရယူခြင်းအား မပြုလုပ်ပါနှင့်"</string>
+ <string name="current_password_text" msgid="8268189555578298067">"သင့်လက်ရှိ အရံသိမ်းဆည်းမှု လျှို့ဝှက်စကားဝှက်အား ထည့်သွင်းပါ။"</string>
+ <string name="device_encryption_restore_text" msgid="1570864916855208992">"သင့်စက်၏ လျှို့ဝှက်အသွင်ပြောင်းခြင်းအတွက်စကားဝှက်ကို ထည့်သွင်းပါ။"</string>
+ <string name="device_encryption_backup_text" msgid="5866590762672844664">"သင့်စက်၏လျှို့ဝှက်အသွင်ပြောင်းခြင်းအတွက် လျှို့ဝှက်စကားဝှက်အားထည့်ပါ။ အရံသိမ်းဆည်းမှု သိမ်းဆည်းနေရာတွင်လည်း အသုံးပြုမည်ဖြစ်သည်။"</string>
+ <string name="backup_enc_password_text" msgid="4981585714795233099">"ဒေတာအားလုံးအားအရန်သိမ်းဆည်းခြင်းပြီးလျှို့ဝှက်အသွင်ပြောင်းခြင်းအတွက် လျှို့ဝှက်နံပါတ်/စာကိုထည့်ပါ။ အကယ်၍ ကွက်လပ်ထားပါက ယခုသင့်လက်ရှိလျှို့ဝှက်စကားဝှက်အား အသုံးပြုပါမည်။"</string>
+ <string name="backup_enc_password_optional" msgid="1350137345907579306">"အကယ်၍ ဒေတာအားလုံးအားအရန်သိမ်းဆည်းခြင်းကို ဝှက်လိုပါက အောက်တွင်လျှို့ဝှက်နံပါတ်/စာကိုထည့်ပါ။"</string>
+ <string name="backup_enc_password_required" msgid="7889652203371654149">"သင်၏ ကိရိယာကို လျှို့ဝျက်ကုဒ် သွင်းထားရာ၊ သင်သည် သင်၏ ဘက်အာပ်ကိုပါ လျှို့ဝျက်ကုဒ် သွင်းရန် လိုအပ်သည်။ ကျေးဇူးပြုပြီး အောက်မှာ စကားဝှက်ကို ထည့်သွင်းပါ:"</string>
+ <string name="restore_enc_password_text" msgid="6140898525580710823">"အကယ်၍ ပြန်လည်ရယူမည့်ဒေတာမှာလျှို့ဝှက်အသွင်ပြောင်းထားပါက အောက်တွင်စကားဝှက်ကိုထည့်ပါ-"</string>
<string name="toast_backup_started" msgid="550354281452756121">"Backupစတင်ပြုလုပ်နေသည်"</string>
<string name="toast_backup_ended" msgid="3818080769548726424">"Backupလုပ်ခြင်းပြီးဆုံးပါပြီ"</string>
<string name="toast_restore_started" msgid="7881679218971277385">"ပြန်လည်ရယူခြင်း စတင်ပြုလုပ်နေသည်"</string>
diff --git a/packages/BackupRestoreConfirmation/res/values-ne-rNP/strings.xml b/packages/BackupRestoreConfirmation/res/values-ne-rNP/strings.xml
index 993311d..473802e 100644
--- a/packages/BackupRestoreConfirmation/res/values-ne-rNP/strings.xml
+++ b/packages/BackupRestoreConfirmation/res/values-ne-rNP/strings.xml
@@ -29,8 +29,7 @@
<string name="device_encryption_backup_text" msgid="5866590762672844664">"कृपया तल तपाईंको उपकरण एन्क्रिप्सन पासवर्ड प्रविष्टि गर्नुहोस्: यो ब्याकप सँग्रह एन्क्रिप्ट गर्न पनि प्रयोग हुने छ।"</string>
<string name="backup_enc_password_text" msgid="4981585714795233099">"ब्याकप डेटालाई encrypt गर्न पासवर्ड प्रविष्टि गर्नुहोस्, यदि यो खालि छोडिएको खण्डमा तपाईको पुरानै पासवर्ड प्रयोग हुने छ।"</string>
<string name="backup_enc_password_optional" msgid="1350137345907579306">"यदि तपाईं पूर्ण ब्याकअप डेटा इन्क्रिप्ट गर्न चाहनु हुन्छ भने तल पासवर्ड प्रविष्टि गर्नुहोस्।"</string>
- <!-- no translation found for backup_enc_password_required (7889652203371654149) -->
- <skip />
+ <string name="backup_enc_password_required" msgid="7889652203371654149">"तपाईँको उपकरण गुप्तिकरण गरिए देखि, तपाईंले आफ्नो जगेडा गुप्तिकरण गर्न आवश्यक छ। कृपया तल पासवर्ड प्रविष्ट गर्नुहोस्:"</string>
<string name="restore_enc_password_text" msgid="6140898525580710823">"यदि पुनःबहाली डेटा इन्क्रिप्ट छ भने कृपया तल पासवर्ड प्रविष्टि गर्नुहोस्:"</string>
<string name="toast_backup_started" msgid="550354281452756121">"जगेडा राख्न सुरु हुँदै..."</string>
<string name="toast_backup_ended" msgid="3818080769548726424">"ब्याकअप सकियो"</string>
diff --git a/packages/BackupRestoreConfirmation/res/values-si-rLK/strings.xml b/packages/BackupRestoreConfirmation/res/values-si-rLK/strings.xml
index 8d1ede4..aaeaf04 100644
--- a/packages/BackupRestoreConfirmation/res/values-si-rLK/strings.xml
+++ b/packages/BackupRestoreConfirmation/res/values-si-rLK/strings.xml
@@ -29,8 +29,7 @@
<string name="device_encryption_backup_text" msgid="5866590762672844664">"කරුණාකර ඔබගේ උපාංගයේ සංකේතන මුරපදය පහත ඇතුලත් කරන්න. සංරක්ෂිත උපස්ථ සංකේතනය කිරීමට මෙය භාවිත කළ හැක."</string>
<string name="backup_enc_password_text" msgid="4981585714795233099">"කරුණාකර සියලු උපස්ථ දත්ත සංකේතනය කිරීම සඳහා භාවිතයට මුරපදයක් ඇතුළත් කරන්න. මෙය හිස්ව තැබුවොත්, ඔබගේ වර්තමාන උපස්ථ මුරපදය භාවිත වෙයි:"</string>
<string name="backup_enc_password_optional" msgid="1350137345907579306">"සියලු උපස්ථ දත්ත සංකේතනය කිරීමට ඔබ අදහස් කරන්නේ නම්, මුරපදය පහලින් ඇතුලත් කරන්න:"</string>
- <!-- no translation found for backup_enc_password_required (7889652203371654149) -->
- <skip />
+ <string name="backup_enc_password_required" msgid="7889652203371654149">"ඔබගේ උපාංගය සංකේතනය කර තිබෙන නිසා, ඔබගේ උපස්ථය සංකේතනය ඔබට අවශ්ය වී තිබේ. කරුණාකර මුරපදය පහළින් එකතු කරන්න:"</string>
<string name="restore_enc_password_text" msgid="6140898525580710823">"යළි පිහිටුවන දත්ත සංකේතනය කරන ලද ඒවානම්, කරුණාකර මුරපදය පහලින් ඇතුල් කරන්න:"</string>
<string name="toast_backup_started" msgid="550354281452756121">"උපස්ථ කිරීම ආරම්භ කරමින්..."</string>
<string name="toast_backup_ended" msgid="3818080769548726424">"උපස්ථය අවසන්"</string>
diff --git a/packages/BackupRestoreConfirmation/res/values-ur-rPK/strings.xml b/packages/BackupRestoreConfirmation/res/values-ur-rPK/strings.xml
index 416b693..6f1c9b5 100644
--- a/packages/BackupRestoreConfirmation/res/values-ur-rPK/strings.xml
+++ b/packages/BackupRestoreConfirmation/res/values-ur-rPK/strings.xml
@@ -29,8 +29,7 @@
<string name="device_encryption_backup_text" msgid="5866590762672844664">"براہ کرم ذیل میں اپنے آلہ کی مرموز کاری کا پاس ورڈ درج کریں۔ یہ بیک اپ آرکائیو کی مرموز کاری کرنے کیلئے بھی استعمال کیا جائے گا۔"</string>
<string name="backup_enc_password_text" msgid="4981585714795233099">"مکمل بیک اپ ڈیٹا کی مرموز کاری کرنے کیلئے استعمال کیلئے براہ کرم ایک پاس ورڈ درج کریں۔ اگر یہ خالی رہتا ہے تو آپ کا موجودہ بیک اپ پاس ورڈ استعمال کیا جائے گا:"</string>
<string name="backup_enc_password_optional" msgid="1350137345907579306">"اگر آپ مکمل بیک اپ ڈیٹا کی مرموز کاری کرنا چاہتے ہیں تو ذیل میں ایک پاس ورڈ درج کریں:"</string>
- <!-- no translation found for backup_enc_password_required (7889652203371654149) -->
- <skip />
+ <string name="backup_enc_password_required" msgid="7889652203371654149">"چونکہ آپ کا آلہ مرموز کردہ ہے، آپ کو اپنے بیک اپ کی مرموز کاری کرنے کی ضرورت ہے۔ براہ کرم ذیل میں ایک پاس ورڈ درج کریں:"</string>
<string name="restore_enc_password_text" msgid="6140898525580710823">"اگر بحال ہونے والا ڈیٹا مرموز کردہ ہے تو براہ کرم ذیل میں پاس ورڈ درج کریں:"</string>
<string name="toast_backup_started" msgid="550354281452756121">"بیک اپ شروع ہو رہا ہے…"</string>
<string name="toast_backup_ended" msgid="3818080769548726424">"بیک اپ مکمل ہو گیا"</string>
diff --git a/packages/BackupRestoreConfirmation/res/values-uz-rUZ/strings.xml b/packages/BackupRestoreConfirmation/res/values-uz-rUZ/strings.xml
index 032f884..1b5741f 100644
--- a/packages/BackupRestoreConfirmation/res/values-uz-rUZ/strings.xml
+++ b/packages/BackupRestoreConfirmation/res/values-uz-rUZ/strings.xml
@@ -29,8 +29,7 @@
<string name="device_encryption_backup_text" msgid="5866590762672844664">"Qurilmangizning shifr parolini kiriting. U zahira arxivni shifrlash uchun ham ishlatiladi."</string>
<string name="backup_enc_password_text" msgid="4981585714795233099">"To‘liq zahira fayllarini shifrlash uchun parol kiriting. Agar bo‘sh qoldirsangiz, joriy zahiralash parolingizdan foydalaniladi:"</string>
<string name="backup_enc_password_optional" msgid="1350137345907579306">"To‘liq zahira ma’lumotlarini shifrlashni xohlasangiz, quyidagi parolni kiriting:"</string>
- <!-- no translation found for backup_enc_password_required (7889652203371654149) -->
- <skip />
+ <string name="backup_enc_password_required" msgid="7889652203371654149">"Qurilmangiz shifrlangani bois ma’lumotlaringizning zaxira nusxasini ham shifrlash zarur. Shifrlash uchun parolni kiriting:"</string>
<string name="restore_enc_password_text" msgid="6140898525580710823">"Agar tiklash ma’lumoti shifrlangan bo‘lsa, pastga parolni kiriting:"</string>
<string name="toast_backup_started" msgid="550354281452756121">"Zahiralash jarayoni boshlandi..."</string>
<string name="toast_backup_ended" msgid="3818080769548726424">"Zahiralash jarayoni bajarildi"</string>
diff --git a/packages/CaptivePortalLogin/res/values-my-rMM/strings.xml b/packages/CaptivePortalLogin/res/values-my-rMM/strings.xml
index cd90b38..603a804 100644
--- a/packages/CaptivePortalLogin/res/values-my-rMM/strings.xml
+++ b/packages/CaptivePortalLogin/res/values-my-rMM/strings.xml
@@ -3,6 +3,6 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
<string name="action_use_network" msgid="6076184727448466030">"ဒီကွန်ရက်ကို လက်ရှိအတိုင်း သုံးရန်"</string>
- <string name="action_do_not_use_network" msgid="4577366536956516683">"ဒီကွန်ရက်ကို မသုံးပါနှင့်"</string>
+ <string name="action_do_not_use_network" msgid="4577366536956516683">"ဒီကွန်ရက်ကို မသုံးပါနှင့်"</string>
<string name="action_bar_label" msgid="2573986763322074279">"ကွန်ရက်သို့ လက်မှတ်ထိုး ဝင်ရန်"</string>
</resources>
diff --git a/packages/DocumentsUI/res/values-hi/strings.xml b/packages/DocumentsUI/res/values-hi/strings.xml
index c4dc652..88f26ed 100644
--- a/packages/DocumentsUI/res/values-hi/strings.xml
+++ b/packages/DocumentsUI/res/values-hi/strings.xml
@@ -18,7 +18,7 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"दस्तावेज़"</string>
<string name="title_open" msgid="4353228937663917801">"यहां से खोलें"</string>
- <string name="title_save" msgid="2433679664882857999">"यहां सहेजें"</string>
+ <string name="title_save" msgid="2433679664882857999">"यहां जोड़ें"</string>
<string name="menu_create_dir" msgid="5947289605844398389">"फ़ोल्डर बनाएं"</string>
<string name="menu_grid" msgid="6878021334497835259">"ग्रिड दृश्य"</string>
<string name="menu_list" msgid="7279285939892417279">"सूची दृश्य"</string>
@@ -26,13 +26,13 @@
<string name="menu_search" msgid="3816712084502856974">"खोजें"</string>
<string name="menu_settings" msgid="6008033148948428823">"सेटिंग"</string>
<string name="menu_open" msgid="432922957274920903">"खोलें"</string>
- <string name="menu_save" msgid="2394743337684426338">"सहेजें"</string>
+ <string name="menu_save" msgid="2394743337684426338">"जोड़ें"</string>
<string name="menu_share" msgid="3075149983979628146">"साझा करें"</string>
<string name="menu_delete" msgid="8138799623850614177">"हटाएं"</string>
<string name="menu_select" msgid="8711270657353563424">"\"<xliff:g id="DIRECTORY">^1</xliff:g>\" चुनें"</string>
- <string name="menu_advanced_show" product="nosdcard" msgid="4693652895715631401">"आंतरिक संग्रहण दिखाएं"</string>
+ <string name="menu_advanced_show" product="nosdcard" msgid="4693652895715631401">"आंतरिक मेमोरी दिखाएं"</string>
<string name="menu_advanced_show" product="default" msgid="5792182900084144261">"SD कार्ड दिखाएं"</string>
- <string name="menu_advanced_hide" product="nosdcard" msgid="4218809952721972589">"आंतरिक संग्रहण छिपाएं"</string>
+ <string name="menu_advanced_hide" product="nosdcard" msgid="4218809952721972589">"आंतरिक मेमोरी छिपाएं"</string>
<string name="menu_advanced_hide" product="default" msgid="4845869969015718848">"SD कार्ड छिपाएं"</string>
<string name="menu_file_size_show" msgid="3240323619260823076">"फ़ाइल आकार दिखाएं"</string>
<string name="menu_file_size_hide" msgid="8881975928502581042">"फ़ाइल आकार छिपाएं"</string>
@@ -46,10 +46,10 @@
<string name="create_error" msgid="3735649141335444215">"फ़ोल्डर बनाने में विफल"</string>
<string name="query_error" msgid="1222448261663503501">"दस्तावेजों के लिए क्वेरी करने में विफल रहा"</string>
<string name="root_recent" msgid="4470053704320518133">"हाल ही के"</string>
- <string name="root_available_bytes" msgid="8568452858617033281">"<xliff:g id="SIZE">%1$s</xliff:g> रिक्त"</string>
- <string name="root_type_service" msgid="2178854894416775409">"संग्रहण सेवाएं"</string>
+ <string name="root_available_bytes" msgid="8568452858617033281">"<xliff:g id="SIZE">%1$s</xliff:g> खाली"</string>
+ <string name="root_type_service" msgid="2178854894416775409">"मेमोरी सेवाएं"</string>
<string name="root_type_shortcut" msgid="3318760609471618093">"शॉर्टकट"</string>
- <string name="root_type_device" msgid="7121342474653483538">"उपकरण"</string>
+ <string name="root_type_device" msgid="7121342474653483538">"डिवाइस"</string>
<string name="root_type_apps" msgid="8838065367985945189">"अधिक ऐप्स"</string>
<string name="empty" msgid="7858882803708117596">"कोई आइटम नहीं"</string>
<string name="toast_no_application" msgid="1339885974067891667">"फ़ाइल नहीं खोली जा सकती"</string>
diff --git a/packages/DocumentsUI/res/values-my-rMM/strings.xml b/packages/DocumentsUI/res/values-my-rMM/strings.xml
index 98b3a90..50f8363 100644
--- a/packages/DocumentsUI/res/values-my-rMM/strings.xml
+++ b/packages/DocumentsUI/res/values-my-rMM/strings.xml
@@ -26,7 +26,7 @@
<string name="menu_search" msgid="3816712084502856974">"ရှာဖွေရန်"</string>
<string name="menu_settings" msgid="6008033148948428823">"ဆက်တင်များ"</string>
<string name="menu_open" msgid="432922957274920903">"ဖွင့်ရန်"</string>
- <string name="menu_save" msgid="2394743337684426338">"သိမ်းဆည်းရန်"</string>
+ <string name="menu_save" msgid="2394743337684426338">"သိမ်းပါ"</string>
<string name="menu_share" msgid="3075149983979628146">"မျှဝေခြင်း"</string>
<string name="menu_delete" msgid="8138799623850614177">"ဖျက်ပစ်ရန်"</string>
<string name="menu_select" msgid="8711270657353563424">"ရွေးရန်\"<xliff:g id="DIRECTORY">^1</xliff:g>\""</string>
diff --git a/packages/DocumentsUI/res/values-pt/strings.xml b/packages/DocumentsUI/res/values-pt/strings.xml
index 184fb53..2aaa4d2 100644
--- a/packages/DocumentsUI/res/values-pt/strings.xml
+++ b/packages/DocumentsUI/res/values-pt/strings.xml
@@ -50,7 +50,7 @@
<string name="root_type_service" msgid="2178854894416775409">"Serviços de armazenamento"</string>
<string name="root_type_shortcut" msgid="3318760609471618093">"Atalhos"</string>
<string name="root_type_device" msgid="7121342474653483538">"Dispositivos"</string>
- <string name="root_type_apps" msgid="8838065367985945189">"Mais aplicativos"</string>
+ <string name="root_type_apps" msgid="8838065367985945189">"Mais apps"</string>
<string name="empty" msgid="7858882803708117596">"Nenhum item"</string>
<string name="toast_no_application" msgid="1339885974067891667">"Não é possível abrir o arquivo"</string>
<string name="toast_failed_delete" msgid="2180678019407244069">"Não foi possível excluir alguns documentos"</string>
diff --git a/packages/DocumentsUI/res/values-zh-rTW/strings.xml b/packages/DocumentsUI/res/values-zh-rTW/strings.xml
index a37dbe8..464a13e 100644
--- a/packages/DocumentsUI/res/values-zh-rTW/strings.xml
+++ b/packages/DocumentsUI/res/values-zh-rTW/strings.xml
@@ -45,7 +45,7 @@
<string name="save_error" msgid="6167009778003223664">"無法儲存文件"</string>
<string name="create_error" msgid="3735649141335444215">"無法建立資料夾"</string>
<string name="query_error" msgid="1222448261663503501">"無法查詢文件"</string>
- <string name="root_recent" msgid="4470053704320518133">"最近存取過"</string>
+ <string name="root_recent" msgid="4470053704320518133">"最近"</string>
<string name="root_available_bytes" msgid="8568452858617033281">"可用空間:<xliff:g id="SIZE">%1$s</xliff:g>"</string>
<string name="root_type_service" msgid="2178854894416775409">"儲存空間服務"</string>
<string name="root_type_shortcut" msgid="3318760609471618093">"捷徑"</string>
diff --git a/packages/ExternalStorageProvider/res/values-hi/strings.xml b/packages/ExternalStorageProvider/res/values-hi/strings.xml
index 1227bd4..8538081 100644
--- a/packages/ExternalStorageProvider/res/values-hi/strings.xml
+++ b/packages/ExternalStorageProvider/res/values-hi/strings.xml
@@ -16,7 +16,7 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_label" msgid="7123375275748530234">"बाहरी संग्रहण"</string>
- <string name="root_internal_storage" msgid="827844243068584127">"मोबाइल संग्रहण"</string>
+ <string name="app_label" msgid="7123375275748530234">"बाहरी मेमोरी"</string>
+ <string name="root_internal_storage" msgid="827844243068584127">"मोबाइल मेमोरी"</string>
<string name="root_documents" msgid="4051252304075469250">"दस्तावेज़"</string>
</resources>
diff --git a/packages/ExternalStorageProvider/res/values-my-rMM/strings.xml b/packages/ExternalStorageProvider/res/values-my-rMM/strings.xml
index 643fb92..dc9d684 100644
--- a/packages/ExternalStorageProvider/res/values-my-rMM/strings.xml
+++ b/packages/ExternalStorageProvider/res/values-my-rMM/strings.xml
@@ -17,6 +17,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="7123375275748530234">"ပြင်ပသိုလှောင်ရာပစ္စည်း"</string>
- <string name="root_internal_storage" msgid="827844243068584127">"စက်အတွင်းသိမ်းဆည်းရန်နေရာ"</string>
+ <string name="root_internal_storage" msgid="827844243068584127">"စက်တွင်း သိုလှောင်ထားမှု"</string>
<string name="root_documents" msgid="4051252304075469250">"စာရွက်စာတန်းများ"</string>
</resources>
diff --git a/packages/InputDevices/res/values-hi/strings.xml b/packages/InputDevices/res/values-hi/strings.xml
index 77cb8fe..fcd7f84 100644
--- a/packages/InputDevices/res/values-hi/strings.xml
+++ b/packages/InputDevices/res/values-hi/strings.xml
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_label" msgid="8016145283189546017">"इनपुट उपकरण"</string>
+ <string name="app_label" msgid="8016145283189546017">"इनपुट डिवाइस"</string>
<string name="keyboard_layouts_label" msgid="6688773268302087545">"Android कीबोर्ड"</string>
<string name="keyboard_layout_english_uk_label" msgid="6664258463319999632">"अंग्रेज़ी (यूके)"</string>
<string name="keyboard_layout_english_us_label" msgid="8994890249649106291">"अंग्रेज़ी (यूएस)"</string>
diff --git a/packages/Keyguard/res/values-bn-rBD/strings.xml b/packages/Keyguard/res/values-bn-rBD/strings.xml
index 0473e48..e315f7a 100644
--- a/packages/Keyguard/res/values-bn-rBD/strings.xml
+++ b/packages/Keyguard/res/values-bn-rBD/strings.xml
@@ -22,9 +22,9 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_name" msgid="719438068451601849">"কীগার্ড"</string>
<string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"PIN কোড লিখুন"</string>
- <string name="keyguard_password_enter_puk_code" msgid="3035856550289724338">"SIM PUK এবং নতুন PIN কোড লিখুন"</string>
- <string name="keyguard_password_enter_puk_prompt" msgid="1801941051094974609">"SIM PUK কোড"</string>
- <string name="keyguard_password_enter_pin_prompt" msgid="3201151840570492538">"নতুন SIM PIN কোড"</string>
+ <string name="keyguard_password_enter_puk_code" msgid="3035856550289724338">"সিম PUK এবং নতুন PIN কোড লিখুন"</string>
+ <string name="keyguard_password_enter_puk_prompt" msgid="1801941051094974609">"সিম PUK কোড"</string>
+ <string name="keyguard_password_enter_pin_prompt" msgid="3201151840570492538">"নতুন সিম PIN কোড"</string>
<string name="keyguard_password_entry_touch_hint" msgid="7858547464982981384"><font size="17">"পাসওয়ার্ড লিখতে স্পর্শ করুন"</font></string>
<string name="keyguard_password_enter_password_code" msgid="1054721668279049780">"আনলক করতে পাসওয়ার্ড লিখুন"</string>
<string name="keyguard_password_enter_pin_password_code" msgid="6391755146112503443">"আনলক করতে PIN লিখুন"</string>
@@ -36,16 +36,16 @@
<string name="keyguard_low_battery" msgid="8143808018719173859">"আপনার চার্জার সংযুক্ত করুন৷"</string>
<string name="keyguard_instructions_when_pattern_disabled" msgid="1332288268600329841">"আনলক করতে মেনু টিপুন৷"</string>
<string name="keyguard_network_locked_message" msgid="9169717779058037168">"নেটওয়ার্ক লক হয়েছে"</string>
- <string name="keyguard_missing_sim_message_short" msgid="494980561304211931">"কোনো SIM কার্ড নেই"</string>
- <string name="keyguard_missing_sim_message" product="tablet" msgid="1445849005909260039">"ট্যাবলেটের মধ্যে কোনো SIM কার্ড নেই৷"</string>
- <string name="keyguard_missing_sim_message" product="default" msgid="3481110395508637643">"ফোনের মধ্যে কোনো SIM কার্ড নেই৷"</string>
- <string name="keyguard_missing_sim_instructions" msgid="5210891509995942250">"একটি SIM কার্ড ঢোকান৷"</string>
- <string name="keyguard_missing_sim_instructions_long" msgid="5968985489463870358">"SIM কার্ডটি অনুপস্থিত বা পাঠযোগ্য নয়৷ একটি SIM কার্ড ঢোকান৷"</string>
- <string name="keyguard_permanent_disabled_sim_message_short" msgid="8340813989586622356">"অব্যবহারযোগ্য SIM কার্ড৷"</string>
- <string name="keyguard_permanent_disabled_sim_instructions" msgid="5892940909699723544">"আপনার SIM কার্ড স্থায়ীভাবে অক্ষম করা হয়েছে৷\n অন্য একটি SIM কার্ড পেতে আপনার ওয়্যারলেস পরিষেবা প্রদানকারীর সাথে যোগাযোগ করুন৷"</string>
- <string name="keyguard_sim_locked_message" msgid="6875773413306380902">"SIM কার্ড লক করা আছে৷"</string>
- <string name="keyguard_sim_puk_locked_message" msgid="3747232467471801633">"SIM কার্ডটি PUK কোড দিয়ে লক করা আছে৷"</string>
- <string name="keyguard_sim_unlock_progress_dialog_message" msgid="7975221805033614426">"SIM কার্ড আনলক করা হচ্ছে…"</string>
+ <string name="keyguard_missing_sim_message_short" msgid="494980561304211931">"কোনো সিম কার্ড নেই"</string>
+ <string name="keyguard_missing_sim_message" product="tablet" msgid="1445849005909260039">"ট্যাবলেটের মধ্যে কোনো সিম কার্ড নেই৷"</string>
+ <string name="keyguard_missing_sim_message" product="default" msgid="3481110395508637643">"ফোনের মধ্যে কোনো সিম কার্ড নেই৷"</string>
+ <string name="keyguard_missing_sim_instructions" msgid="5210891509995942250">"একটি সিম কার্ড ঢোকান৷"</string>
+ <string name="keyguard_missing_sim_instructions_long" msgid="5968985489463870358">"সিম কার্ডটি অনুপস্থিত বা পাঠযোগ্য নয়৷ একটি সিম কার্ড ঢোকান৷"</string>
+ <string name="keyguard_permanent_disabled_sim_message_short" msgid="8340813989586622356">"অব্যবহারযোগ্য সিম কার্ড৷"</string>
+ <string name="keyguard_permanent_disabled_sim_instructions" msgid="5892940909699723544">"আপনার সিম কার্ড স্থায়ীভাবে অক্ষম করা হয়েছে৷\n অন্য একটি সিম কার্ড পেতে আপনার ওয়্যারলেস পরিষেবা প্রদানকারীর সাথে যোগাযোগ করুন৷"</string>
+ <string name="keyguard_sim_locked_message" msgid="6875773413306380902">"সিম কার্ড লক করা আছে৷"</string>
+ <string name="keyguard_sim_puk_locked_message" msgid="3747232467471801633">"সিম কার্ডটি PUK কোড দিয়ে লক করা আছে৷"</string>
+ <string name="keyguard_sim_unlock_progress_dialog_message" msgid="7975221805033614426">"সিম কার্ড আনলক করা হচ্ছে…"</string>
<string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s৷ %3$d এর %2$d উইজেট৷"</string>
<string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"উইজেট যোগ করুন"</string>
<string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"খালি"</string>
@@ -106,13 +106,13 @@
<string name="kg_wrong_pin" msgid="1131306510833563801">"ভুল PIN"</string>
<string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"<xliff:g id="NUMBER">%d</xliff:g> সেকেন্ডের মধ্যে আবার চেষ্টা করুন৷"</string>
<string name="kg_pattern_instructions" msgid="398978611683075868">"আপনার প্যাটার্ন আঁকুন"</string>
- <string name="kg_sim_pin_instructions" msgid="2319508550934557331">"SIM PIN লিখুন"</string>
+ <string name="kg_sim_pin_instructions" msgid="2319508550934557331">"সিম PIN লিখুন"</string>
<string name="kg_pin_instructions" msgid="2377242233495111557">"PIN লিখুন"</string>
<string name="kg_password_instructions" msgid="5753646556186936819">"পাসওয়ার্ড লিখুন"</string>
- <string name="kg_puk_enter_puk_hint" msgid="453227143861735537">"SIM এখন অক্ষম করা হয়েছে৷ অবিরত থাকতে PUK কোডটি লিখুন৷ বিশদ বিবরণের জন্য ক্যারিয়ারের সাথে যোগাযোগ করুন৷"</string>
+ <string name="kg_puk_enter_puk_hint" msgid="453227143861735537">"সিম এখন অক্ষম করা হয়েছে৷ অবিরত থাকতে PUK কোডটি লিখুন৷ বিশদ বিবরণের জন্য ক্যারিয়ারের সাথে যোগাযোগ করুন৷"</string>
<string name="kg_puk_enter_pin_hint" msgid="7871604527429602024">"কাঙ্ক্ষিত PIN কোড লিখুন"</string>
<string name="kg_enter_confirm_pin_hint" msgid="325676184762529976">"কাঙ্ক্ষিত PIN কোড নিশ্চিত করুন"</string>
- <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"SIM কার্ড আনলক করা হচ্ছে…"</string>
+ <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"সিম কার্ড আনলক করা হচ্ছে…"</string>
<string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"৪ থেকে ৮টি সংখ্যার একটি PIN লিখুন৷"</string>
<string name="kg_invalid_sim_puk_hint" msgid="7553388325654369575">"PUK কোডটিকে ৮টি বা তার বেশি সংখ্য বিশিষ্ট হতে হবে৷"</string>
<string name="kg_invalid_puk" msgid="3638289409676051243">"সঠিক PUK কোড পুনরায় লিখুন৷ বার বার প্রচেষ্টা করা হলে তা স্থায়ীভাবে সিমটিকে অক্ষম করে দেবে৷"</string>
@@ -136,18 +136,18 @@
<string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"আপনি আপনার আনলকের প্যাটার্ন আঁকার ক্ষেত্রে <xliff:g id="NUMBER_0">%d</xliff:g> বার ভুল করেছেন৷ আর <xliff:g id="NUMBER_1">%d</xliff:g> বার অসফল প্রচেষ্টা করা হলে আপনাকে একটি ইমেল অ্যাকাউন্ট মারফত আপনার ফোন আনলক করতে বলা হবে৷\n\n <xliff:g id="NUMBER_2">%d</xliff:g> সেকেন্ডের মধ্যে আবার চেষ্টা করুন৷"</string>
<string name="kg_text_message_separator" product="default" msgid="4160700433287233771">" — "</string>
<string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"সরান"</string>
- <string name="kg_password_wrong_pin_code_pukked" msgid="30531039455764924">"ভুল SIM PIN কোড, আপনার ডিভাইসটি আনলক করতে এখন আপনাকে অবশ্যই আপনার ক্যারিয়ারের সাথে যোগাযোগ করতে হবে৷"</string>
+ <string name="kg_password_wrong_pin_code_pukked" msgid="30531039455764924">"ভুল সিম PIN কোড, আপনার ডিভাইসটি আনলক করতে এখন আপনাকে অবশ্যই আপনার ক্যারিয়ারের সাথে যোগাযোগ করতে হবে৷"</string>
<plurals name="kg_password_wrong_pin_code">
- <item quantity="one" msgid="8134313997799638254">"ভুল SIM PIN কোড, আপনার কাছে আর <xliff:g id="NUMBER">%d</xliff:g>টি প্রচেষ্টা বাকি রয়েছে, তার পরে আপনার ডিভাইসটি আনলক করতে আপনাকে অবশ্যই আপনার ক্যারিয়ারের সাথে যোগাযোগ করতে হবে৷"</item>
- <item quantity="other" msgid="2215723361575359486">"ভুল SIM PIN কোড, আপনার কাছে আর <xliff:g id="NUMBER">%d</xliff:g>টি প্রচেষ্টা বাকি রয়েছে৷"</item>
+ <item quantity="one" msgid="8134313997799638254">"ভুল সিম PIN কোড, আপনার কাছে আর <xliff:g id="NUMBER">%d</xliff:g>টি প্রচেষ্টা বাকি রয়েছে, তার পরে আপনার ডিভাইসটি আনলক করতে আপনাকে অবশ্যই আপনার ক্যারিয়ারের সাথে যোগাযোগ করতে হবে৷"</item>
+ <item quantity="other" msgid="2215723361575359486">"ভুল সিম PIN কোড, আপনার কাছে আর <xliff:g id="NUMBER">%d</xliff:g>টি প্রচেষ্টা বাকি রয়েছে৷"</item>
</plurals>
<string name="kg_password_wrong_puk_code_dead" msgid="7077536808291316208">"SIMটি ব্যবহারের অযোগ্য৷ আপনার ক্যারিয়ারের সাথে যোগাযোগ করুন৷"</string>
<plurals name="kg_password_wrong_puk_code">
- <item quantity="one" msgid="3256893607561060649">"ভুল SIM PUK কোড, আপনার কাছে আর <xliff:g id="NUMBER">%d</xliff:g>টি প্রচেষ্টা বাকি রয়েছে এটির পরেই আপনার SIM স্থায়ীভাবে অব্যবহারযোগ্য হবে৷"</item>
- <item quantity="other" msgid="5477305226026342036">"ভুল SIM PUK কোড, আপনার কাছে আর <xliff:g id="NUMBER">%d</xliff:g>টি প্রচেষ্টা বাকি রয়েছে এটির পরেই আপনার SIM স্থায়ীভাবে অব্যবহারযোগ্য হবে৷"</item>
+ <item quantity="one" msgid="3256893607561060649">"ভুল সিম PUK কোড, আপনার কাছে আর <xliff:g id="NUMBER">%d</xliff:g>টি প্রচেষ্টা বাকি রয়েছে এটির পরেই আপনার সিম স্থায়ীভাবে অব্যবহারযোগ্য হবে৷"</item>
+ <item quantity="other" msgid="5477305226026342036">"ভুল সিম PUK কোড, আপনার কাছে আর <xliff:g id="NUMBER">%d</xliff:g>টি প্রচেষ্টা বাকি রয়েছে এটির পরেই আপনার সিম স্থায়ীভাবে অব্যবহারযোগ্য হবে৷"</item>
</plurals>
- <string name="kg_password_pin_failed" msgid="6268288093558031564">"SIM PIN ক্রিয়াকলাপটি ব্যর্থ হয়েছে!"</string>
- <string name="kg_password_puk_failed" msgid="2838824369502455984">"SIM PUK ক্রিয়াকলাপটি ব্যর্থ হয়েছে!"</string>
+ <string name="kg_password_pin_failed" msgid="6268288093558031564">"সিম PIN ক্রিয়াকলাপটি ব্যর্থ হয়েছে!"</string>
+ <string name="kg_password_puk_failed" msgid="2838824369502455984">"সিম PUK ক্রিয়াকলাপটি ব্যর্থ হয়েছে!"</string>
<string name="kg_pin_accepted" msgid="1448241673570020097">"কোড স্বীকৃত হয়েছে!"</string>
<string name="keyguard_transport_prev_description" msgid="8229108430245669854">"পূর্ববর্তী ট্র্যাকে যাওয়ার বোতাম"</string>
<string name="keyguard_transport_next_description" msgid="4299258300283778305">"পরবর্তী ট্র্যাকে যাওয়ার বোতাম"</string>
diff --git a/packages/Keyguard/res/values-hi/strings.xml b/packages/Keyguard/res/values-hi/strings.xml
index 423c2765..5b739db 100644
--- a/packages/Keyguard/res/values-hi/strings.xml
+++ b/packages/Keyguard/res/values-hi/strings.xml
@@ -36,27 +36,27 @@
<string name="keyguard_low_battery" msgid="8143808018719173859">"अपना चार्जर कनेक्ट करें."</string>
<string name="keyguard_instructions_when_pattern_disabled" msgid="1332288268600329841">"अनलॉक करने के लिए मेनू दबाएं."</string>
<string name="keyguard_network_locked_message" msgid="9169717779058037168">"नेटवर्क लॉक किया गया"</string>
- <string name="keyguard_missing_sim_message_short" msgid="494980561304211931">"कोई SIM कार्ड नहीं है"</string>
- <string name="keyguard_missing_sim_message" product="tablet" msgid="1445849005909260039">"टेबलेट में कोई SIM कार्ड नहीं है."</string>
- <string name="keyguard_missing_sim_message" product="default" msgid="3481110395508637643">"फ़ोन में कोई SIM कार्ड नहीं है."</string>
- <string name="keyguard_missing_sim_instructions" msgid="5210891509995942250">"SIM कार्ड डालें."</string>
- <string name="keyguard_missing_sim_instructions_long" msgid="5968985489463870358">"SIM कार्ड गुम है या पढ़ने योग्य नहीं है. SIM कार्ड डालें."</string>
- <string name="keyguard_permanent_disabled_sim_message_short" msgid="8340813989586622356">"अनुपयोगी SIM कार्ड."</string>
- <string name="keyguard_permanent_disabled_sim_instructions" msgid="5892940909699723544">"आपका SIM कार्ड स्थायी रूप से अक्षम कर दिया गया है.\n दूसरे SIM कार्ड के लिए अपने वायरलेस सेवा प्रदाता से संपर्क करें."</string>
+ <string name="keyguard_missing_sim_message_short" msgid="494980561304211931">"कोई सिम कार्ड नहीं है"</string>
+ <string name="keyguard_missing_sim_message" product="tablet" msgid="1445849005909260039">"टेबलेट में कोई सिम कार्ड नहीं है."</string>
+ <string name="keyguard_missing_sim_message" product="default" msgid="3481110395508637643">"फ़ोन में कोई सिम कार्ड नहीं है."</string>
+ <string name="keyguard_missing_sim_instructions" msgid="5210891509995942250">"सिम कार्ड डालें."</string>
+ <string name="keyguard_missing_sim_instructions_long" msgid="5968985489463870358">"सिम कार्ड गुम है या पढ़ने योग्य नहीं है. सिम कार्ड डालें."</string>
+ <string name="keyguard_permanent_disabled_sim_message_short" msgid="8340813989586622356">"अनुपयोगी सिम कार्ड."</string>
+ <string name="keyguard_permanent_disabled_sim_instructions" msgid="5892940909699723544">"आपका सिम कार्ड स्थायी रूप से अक्षम कर दिया गया है.\n दूसरे सिम कार्ड के लिए अपने वायरलेस सेवा प्रदाता से संपर्क करें."</string>
<string name="keyguard_sim_locked_message" msgid="6875773413306380902">"सिम कार्ड लॉक है."</string>
- <string name="keyguard_sim_puk_locked_message" msgid="3747232467471801633">"SIM कार्ड PUK द्वारा लॉक किया हुआ है."</string>
- <string name="keyguard_sim_unlock_progress_dialog_message" msgid="7975221805033614426">"SIM कार्ड अनलॉक हो रहा है…"</string>
+ <string name="keyguard_sim_puk_locked_message" msgid="3747232467471801633">"सिम कार्ड PUK द्वारा लॉक किया हुआ है."</string>
+ <string name="keyguard_sim_unlock_progress_dialog_message" msgid="7975221805033614426">"सिम कार्ड अनलॉक हो रहा है…"</string>
<string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. %3$d विजेट में से %2$d."</string>
<string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"विजेट जोड़ें"</string>
- <string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"रिक्त"</string>
+ <string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"खाली"</string>
<string name="keyguard_accessibility_unlock_area_expanded" msgid="2278106022311170299">"अनलॉक क्षेत्र को विस्तृत कर दिया गया."</string>
<string name="keyguard_accessibility_unlock_area_collapsed" msgid="6366992066936076396">"अनलॉक क्षेत्र को संक्षिप्त कर दिया गया."</string>
<string name="keyguard_accessibility_widget" msgid="6527131039741808240">"<xliff:g id="WIDGET_INDEX">%1$s</xliff:g> विजेट."</string>
<string name="keyguard_accessibility_user_selector" msgid="1226798370913698896">"उपयोगकर्ता चयनकर्ता"</string>
<string name="keyguard_accessibility_camera" msgid="8904231194181114603">"कैमरा"</string>
<string name="keygaurd_accessibility_media_controls" msgid="262209654292161806">"मीडिया नियंत्रण"</string>
- <string name="keyguard_accessibility_widget_reorder_start" msgid="8736853615588828197">"विजेट पुनः क्रमित करना प्रारंभ."</string>
- <string name="keyguard_accessibility_widget_reorder_end" msgid="7170190950870468320">"विजेट पुनः क्रमित करना समाप्त."</string>
+ <string name="keyguard_accessibility_widget_reorder_start" msgid="8736853615588828197">"विजेट फिर से क्रमित करना प्रारंभ."</string>
+ <string name="keyguard_accessibility_widget_reorder_end" msgid="7170190950870468320">"विजेट फिर से क्रमित करना समाप्त."</string>
<string name="keyguard_accessibility_widget_deleted" msgid="4426204263929224434">"विजेट <xliff:g id="WIDGET_INDEX">%1$s</xliff:g> को हटा दिया गया."</string>
<string name="keyguard_accessibility_expand_lock_area" msgid="519859720934178024">"अनलॉक क्षेत्र विस्तृत करें."</string>
<string name="keyguard_accessibility_slide_unlock" msgid="2959928478764697254">"स्लाइड अनलॉक."</string>
@@ -83,7 +83,7 @@
<string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
<string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</string>
<string name="keyboardview_keycode_alt" msgid="4856868820040051939">"Alt"</string>
- <string name="keyboardview_keycode_cancel" msgid="1203984017245783244">"रद्द करें"</string>
+ <string name="keyboardview_keycode_cancel" msgid="1203984017245783244">"रहने दें"</string>
<string name="keyboardview_keycode_delete" msgid="3337914833206635744">"हटाएं"</string>
<string name="keyboardview_keycode_done" msgid="1992571118466679775">"पूर्ण"</string>
<string name="keyboardview_keycode_mode_change" msgid="4547387741906537519">"Mode change"</string>
@@ -111,8 +111,8 @@
<string name="kg_password_instructions" msgid="5753646556186936819">"पासवर्ड डालें"</string>
<string name="kg_puk_enter_puk_hint" msgid="453227143861735537">"सिम अब अक्षम हो गई है. जारी रखने के लिए PUK कोड डालें. विवरण के लिए कैरियर से संपर्क करें."</string>
<string name="kg_puk_enter_pin_hint" msgid="7871604527429602024">"इच्छित पिन कोड डालें"</string>
- <string name="kg_enter_confirm_pin_hint" msgid="325676184762529976">"इच्छित पिन कोड की पुष्टि करें"</string>
- <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"SIM कार्ड अनलॉक कर रहा है…"</string>
+ <string name="kg_enter_confirm_pin_hint" msgid="325676184762529976">"इच्छित पिन कोड की दुबारा पूछें"</string>
+ <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"सिम कार्ड अनलॉक कर रहा है…"</string>
<string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"ऐसा PIN लिखें, जो 4 से 8 अंकों का हो."</string>
<string name="kg_invalid_sim_puk_hint" msgid="7553388325654369575">"PUK कोड 8 या अधिक संख्या वाला होना चाहिए."</string>
<string name="kg_invalid_puk" msgid="3638289409676051243">"सही PUK कोड पुन: डालें. बार-बार प्रयास करने से सिम स्थायी रूप से अक्षम हो जाएगी."</string>
@@ -136,9 +136,9 @@
<string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"आपने अपने अनलॉक आकार को <xliff:g id="NUMBER_0">%d</xliff:g> बार गलत तरीके से आरेखित किया है. <xliff:g id="NUMBER_1">%d</xliff:g> और असफल प्रयासों के बाद, आपसे अपने फ़ोन को किसी ईमेल खाते का उपयोग करके अनलॉक करने के लिए कहा जाएगा.\n\n <xliff:g id="NUMBER_2">%d</xliff:g> सेकंड में पुन: प्रयास करें."</string>
<string name="kg_text_message_separator" product="default" msgid="4160700433287233771">" — "</string>
<string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"निकालें"</string>
- <string name="kg_password_wrong_pin_code_pukked" msgid="30531039455764924">"गलत सिम PIN कोड अपने उपकरण को अनलॉक करने के लिए अब आपको अपने वाहक से संपर्क करना होगा."</string>
+ <string name="kg_password_wrong_pin_code_pukked" msgid="30531039455764924">"गलत सिम PIN कोड अपने डिवाइस को अनलॉक करने के लिए अब आपको अपने वाहक से संपर्क करना होगा."</string>
<plurals name="kg_password_wrong_pin_code">
- <item quantity="one" msgid="8134313997799638254">"गलत सिम PIN कोड, अपने उपकरण को अनलॉक करने के लिए अपने वाहक से संपर्क करने से पहले आपके पास <xliff:g id="NUMBER">%d</xliff:g> प्रयास शेष है."</item>
+ <item quantity="one" msgid="8134313997799638254">"गलत सिम PIN कोड, अपने डिवाइस को अनलॉक करने के लिए अपने वाहक से संपर्क करने से पहले आपके पास <xliff:g id="NUMBER">%d</xliff:g> प्रयास शेष है."</item>
<item quantity="other" msgid="2215723361575359486">"गलत सिम PIN कोड, आपके पास <xliff:g id="NUMBER">%d</xliff:g> प्रयास शेष हैं."</item>
</plurals>
<string name="kg_password_wrong_puk_code_dead" msgid="7077536808291316208">"सिम अनुपयोगी है. अपने वाहक से संपर्क करें."</string>
diff --git a/packages/Keyguard/res/values-iw/strings.xml b/packages/Keyguard/res/values-iw/strings.xml
index 52747cb..06a47d4 100644
--- a/packages/Keyguard/res/values-iw/strings.xml
+++ b/packages/Keyguard/res/values-iw/strings.xml
@@ -119,7 +119,7 @@
<string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"קודי ה-PIN אינם תואמים"</string>
<string name="kg_login_too_many_attempts" msgid="6486842094005698475">"ניסיונות רבים מדי לשרטוט קו ביטול נעילה."</string>
<string name="kg_login_instructions" msgid="1100551261265506448">"כדי לבטל את הנעילה, היכנס באמצעות חשבון Google שלך."</string>
- <string name="kg_login_username_hint" msgid="5718534272070920364">"שם משתמש (דוא\"ל)"</string>
+ <string name="kg_login_username_hint" msgid="5718534272070920364">"שם משתמש (אימייל)"</string>
<string name="kg_login_password_hint" msgid="9057289103827298549">"סיסמה"</string>
<string name="kg_login_submit_button" msgid="5355904582674054702">"היכנס"</string>
<string name="kg_login_invalid_input" msgid="5754664119319872197">"שם משתמש או סיסמה לא חוקיים."</string>
@@ -132,8 +132,8 @@
<string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"ביצעת <xliff:g id="NUMBER_0">%d</xliff:g> ניסיונות שגויים לביטול נעילת הטלפון. לאחר <xliff:g id="NUMBER_1">%d</xliff:g> ניסיונות כושלים נוספים, הטלפון יעבור איפוס לברירת המחדל של היצרן וכל נתוני המשתמש יאבדו."</string>
<string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2072996269148483637">"ביצעת <xliff:g id="NUMBER">%d</xliff:g> ניסיונות שגויים לביטול נעילת הטאבלט. הטאבלט יעבור כעת איפוס לברירת המחדל של היצרן."</string>
<string name="kg_failed_attempts_now_wiping" product="default" msgid="4817627474419471518">"ביצעת <xliff:g id="NUMBER">%d</xliff:g> ניסיונות שגויים לביטול נעילת הטלפון. הטלפון יעבור כעת איפוס לברירת המחדל של היצרן."</string>
- <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"שרטטת את קו ביטול הנעילה באופן שגוי <xliff:g id="NUMBER_0">%d</xliff:g> פעמים. לאחר <xliff:g id="NUMBER_1">%d</xliff:g> ניסיונות כושלים נוספים, תתבקש לבטל את נעילת הטאבלט באמצעות חשבון דוא\"ל.\n\nנסה שוב בעוד <xliff:g id="NUMBER_2">%d</xliff:g> שניות."</string>
- <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"שרטטת את קו ביטול הנעילה באופן שגוי <xliff:g id="NUMBER_0">%d</xliff:g> פעמים. לאחר <xliff:g id="NUMBER_1">%d</xliff:g> ניסיונות כושלים נוספים, תתבקש לבטל את נעילת הטלפון באמצעות חשבון דוא\"ל.\n\nנסה שוב בעוד <xliff:g id="NUMBER_2">%d</xliff:g> שניות."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"שרטטת את קו ביטול הנעילה באופן שגוי <xliff:g id="NUMBER_0">%d</xliff:g> פעמים. לאחר <xliff:g id="NUMBER_1">%d</xliff:g> ניסיונות כושלים נוספים, תתבקש לבטל את נעילת הטאבלט באמצעות חשבון אימייל.\n\nנסה שוב בעוד <xliff:g id="NUMBER_2">%d</xliff:g> שניות."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"שרטטת את קו ביטול הנעילה באופן שגוי <xliff:g id="NUMBER_0">%d</xliff:g> פעמים. לאחר <xliff:g id="NUMBER_1">%d</xliff:g> ניסיונות כושלים נוספים, תתבקש לבטל את נעילת הטלפון באמצעות חשבון אימייל.\n\nנסה שוב בעוד <xliff:g id="NUMBER_2">%d</xliff:g> שניות."</string>
<string name="kg_text_message_separator" product="default" msgid="4160700433287233771">" — "</string>
<string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"הסר"</string>
<string name="kg_password_wrong_pin_code_pukked" msgid="30531039455764924">"מספר PIN שגוי של כרטיס ה-SIM. עליך ליצור כעת קשר עם הספק על מנת לבטל את נעילת המכשיר."</string>
diff --git a/packages/Keyguard/res/values-km-rKH/strings.xml b/packages/Keyguard/res/values-km-rKH/strings.xml
index b21d713..ddaacb6 100644
--- a/packages/Keyguard/res/values-km-rKH/strings.xml
+++ b/packages/Keyguard/res/values-km-rKH/strings.xml
@@ -83,7 +83,7 @@
<string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
<string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</string>
<string name="keyboardview_keycode_alt" msgid="4856868820040051939">"Alt"</string>
- <string name="keyboardview_keycode_cancel" msgid="1203984017245783244">"បោះបង់"</string>
+ <string name="keyboardview_keycode_cancel" msgid="1203984017245783244">"បោះបង់"</string>
<string name="keyboardview_keycode_delete" msgid="3337914833206635744">"លុប"</string>
<string name="keyboardview_keycode_done" msgid="1992571118466679775">"រួចរាល់"</string>
<string name="keyboardview_keycode_mode_change" msgid="4547387741906537519">"ប្ដូររបៀប"</string>
@@ -119,8 +119,8 @@
<string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"កូដ PIN មិនដូចគ្នា"</string>
<string name="kg_login_too_many_attempts" msgid="6486842094005698475">"ព្យាយាមលំនាំច្រើនពេក"</string>
<string name="kg_login_instructions" msgid="1100551261265506448">"ដើម្បីដោះសោ ចូលក្នុងគណនី Google ។"</string>
- <string name="kg_login_username_hint" msgid="5718534272070920364">"ឈ្មោះអ្នកប្រើ (អ៊ីម៉ែល)"</string>
- <string name="kg_login_password_hint" msgid="9057289103827298549">"ពាក្យសម្ងាត់"</string>
+ <string name="kg_login_username_hint" msgid="5718534272070920364">"ឈ្មោះអ្នកប្រើ (អ៊ីមែល)"</string>
+ <string name="kg_login_password_hint" msgid="9057289103827298549">"ពាក្យសម្ងាត់"</string>
<string name="kg_login_submit_button" msgid="5355904582674054702">"ចូល"</string>
<string name="kg_login_invalid_input" msgid="5754664119319872197">"ឈ្មោះអ្នកប្រើ ឬពាក្យសម្ងាត់មិនត្រឹមត្រូវ។"</string>
<string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"ភ្លេចឈ្មោះអ្នកប្រើ ឬពាក្យសម្ងាត់របស់អ្នក?\nមើល "<b>"google.com/accounts/recovery"</b>" ។"</string>
@@ -154,5 +154,5 @@
<string name="keyguard_transport_pause_description" msgid="5093073338238310224">"ប៊ូតុងផ្អាក"</string>
<string name="keyguard_transport_play_description" msgid="2924628863741150956">"ប៊ូតុងចាក់"</string>
<string name="keyguard_transport_stop_description" msgid="3084179324810575787">"ប៊ូតុងបញ្ឈប់"</string>
- <string name="keyguard_carrier_default" msgid="8700650403054042153">"គ្មានសេវា។"</string>
+ <string name="keyguard_carrier_default" msgid="8700650403054042153">"គ្មានសេវា"</string>
</resources>
diff --git a/packages/Keyguard/res/values-kn-rIN/strings.xml b/packages/Keyguard/res/values-kn-rIN/strings.xml
index 2f69388..fcdda42 100644
--- a/packages/Keyguard/res/values-kn-rIN/strings.xml
+++ b/packages/Keyguard/res/values-kn-rIN/strings.xml
@@ -21,14 +21,14 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_name" msgid="719438068451601849">"ಕೀಗಾರ್ಡ್"</string>
- <string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"PIN ಕೋಡ್ ಟೈಪ್ ಮಾಡಿ"</string>
- <string name="keyguard_password_enter_puk_code" msgid="3035856550289724338">"SIM PUK ಮತ್ತು ಹೊಸ PIN ಕೋಡ್ ಟೈಪ್ ಮಾಡಿ"</string>
- <string name="keyguard_password_enter_puk_prompt" msgid="1801941051094974609">"SIM PUK ಕೋಡ್"</string>
- <string name="keyguard_password_enter_pin_prompt" msgid="3201151840570492538">"ಹೊಸ SIM PIN ಕೋಡ್"</string>
+ <string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"ಪಿನ್ ಕೋಡ್ ಟೈಪ್ ಮಾಡಿ"</string>
+ <string name="keyguard_password_enter_puk_code" msgid="3035856550289724338">"ಸಿಮ್ PUK ಮತ್ತು ಹೊಸ ಪಿನ್ ಕೋಡ್ ಟೈಪ್ ಮಾಡಿ"</string>
+ <string name="keyguard_password_enter_puk_prompt" msgid="1801941051094974609">"ಸಿಮ್ PUK ಕೋಡ್"</string>
+ <string name="keyguard_password_enter_pin_prompt" msgid="3201151840570492538">"ಹೊಸ ಸಿಮ್ ಪಿನ್ ಕೋಡ್"</string>
<string name="keyguard_password_entry_touch_hint" msgid="7858547464982981384"><font size="17">"ಪಾಸ್ವರ್ಡ್ ಟೈಪ್ ಮಾಡಲು ಸ್ಪರ್ಶಿಸಿ"</font></string>
<string name="keyguard_password_enter_password_code" msgid="1054721668279049780">"ಅನ್ಲಾಕ್ ಮಾಡಲು ಪಾಸ್ವರ್ಡ್ ಟೈಪ್ ಮಾಡಿ"</string>
- <string name="keyguard_password_enter_pin_password_code" msgid="6391755146112503443">"ಅನ್ಲಾಕ್ ಮಾಡಲು PIN ಟೈಪ್ ಮಾಡಿ"</string>
- <string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"ತಪ್ಪಾದ PIN ಕೋಡ್."</string>
+ <string name="keyguard_password_enter_pin_password_code" msgid="6391755146112503443">"ಅನ್ಲಾಕ್ ಮಾಡಲು ಪಿನ್ ಟೈಪ್ ಮಾಡಿ"</string>
+ <string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"ತಪ್ಪಾದ ಪಿನ್ ಕೋಡ್."</string>
<string name="keyguard_label_text" msgid="861796461028298424">"ಅನ್ಲಾಕ್ ಮಾಡಲು, ಮೆನು ನಂತರ 0 ಒತ್ತಿರಿ."</string>
<string name="faceunlock_multiple_failures" msgid="754137583022792429">"ಗರಿಷ್ಠ ಫೇಸ್ ಅನ್ಲಾಕ್ ಪ್ರಯತ್ನಗಳು ಮೀರಿವೆ"</string>
<string name="keyguard_charged" msgid="3272223906073492454">"ಚಾರ್ಜ್ ಆಗಿದೆ"</string>
@@ -36,16 +36,16 @@
<string name="keyguard_low_battery" msgid="8143808018719173859">"ನಿಮ್ಮ ಚಾರ್ಜರ್ ಸಂಪರ್ಕಗೊಳಿಸಿ."</string>
<string name="keyguard_instructions_when_pattern_disabled" msgid="1332288268600329841">"ಅನ್ಲಾಕ್ ಮಾಡಲು ಮೆನು ಕ್ಲಿಕ್ ಮಾಡಿ."</string>
<string name="keyguard_network_locked_message" msgid="9169717779058037168">"ನೆಟ್ವರ್ಕ್ ಲಾಕ್ ಆಗಿದೆ"</string>
- <string name="keyguard_missing_sim_message_short" msgid="494980561304211931">"SIM ಕಾರ್ಡ್ ಇಲ್ಲ"</string>
- <string name="keyguard_missing_sim_message" product="tablet" msgid="1445849005909260039">"ಟ್ಯಾಬ್ಲೆಟ್ನಲ್ಲಿ ಯಾವುದೇ SIM ಕಾರ್ಡ್ ಇಲ್ಲ."</string>
- <string name="keyguard_missing_sim_message" product="default" msgid="3481110395508637643">"ಪೋನ್ನಲ್ಲಿ ಯಾವುದೇ SIM ಕಾರ್ಡ್ ಇಲ್ಲ."</string>
- <string name="keyguard_missing_sim_instructions" msgid="5210891509995942250">"SIM ಕಾರ್ಡ್ ಸೇರಿಸಿ."</string>
- <string name="keyguard_missing_sim_instructions_long" msgid="5968985489463870358">"SIM ಕಾರ್ಡ್ ಕಾಣೆಯಾಗಿದೆ ಅಥವಾ ಓದಲು ಸಾಧ್ಯವಿಲ್ಲ. ಒಂದು SIM ಕಾರ್ಡ್ ಸೇರಿಸಿ."</string>
- <string name="keyguard_permanent_disabled_sim_message_short" msgid="8340813989586622356">"ನಿಷ್ಪ್ರಯೋಜಕ SIM ಕಾರ್ಡ್."</string>
- <string name="keyguard_permanent_disabled_sim_instructions" msgid="5892940909699723544">"ನಿಮ್ಮ SIM ಕಾರ್ಡ್ ಅನ್ನು ಶಾಶ್ವತವಾಗಿ ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಲಾಗಿದೆ.\n ಮತ್ತೊಂದು SIM ಕಾರ್ಡ್ಗಾಗಿ ನಿಮ್ಮ ವಯರ್ಲೆಸ್ ಸೇವೆಯ ಪೂರೈಕೆದಾರರನ್ನು ಸಂಪರ್ಕಿಸಿ."</string>
- <string name="keyguard_sim_locked_message" msgid="6875773413306380902">"SIM ಕಾರ್ಡ್ ಲಾಕ್ ಮಾಡಲಾಗಿದೆ."</string>
- <string name="keyguard_sim_puk_locked_message" msgid="3747232467471801633">"SIM ಕಾರ್ಡ್ ಅನ್ನು PUK-ಲಾಕ್ ಮಾಡಲಾಗಿದೆ."</string>
- <string name="keyguard_sim_unlock_progress_dialog_message" msgid="7975221805033614426">"SIM ಕಾರ್ಡ್ ಅನ್ಲಾಕ್ ಮಾಡಲಾಗುತ್ತಿದೆ…"</string>
+ <string name="keyguard_missing_sim_message_short" msgid="494980561304211931">"ಸಿಮ್ ಕಾರ್ಡ್ ಇಲ್ಲ"</string>
+ <string name="keyguard_missing_sim_message" product="tablet" msgid="1445849005909260039">"ಟ್ಯಾಬ್ಲೆಟ್ನಲ್ಲಿ ಯಾವುದೇ ಸಿಮ್ ಕಾರ್ಡ್ ಇಲ್ಲ."</string>
+ <string name="keyguard_missing_sim_message" product="default" msgid="3481110395508637643">"ಪೋನ್ನಲ್ಲಿ ಯಾವುದೇ ಸಿಮ್ ಕಾರ್ಡ್ ಇಲ್ಲ."</string>
+ <string name="keyguard_missing_sim_instructions" msgid="5210891509995942250">"ಸಿಮ್ ಕಾರ್ಡ್ ಸೇರಿಸಿ."</string>
+ <string name="keyguard_missing_sim_instructions_long" msgid="5968985489463870358">"ಸಿಮ್ ಕಾರ್ಡ್ ಕಾಣೆಯಾಗಿದೆ ಅಥವಾ ಓದಲು ಸಾಧ್ಯವಿಲ್ಲ. ಒಂದು ಸಿಮ್ ಕಾರ್ಡ್ ಸೇರಿಸಿ."</string>
+ <string name="keyguard_permanent_disabled_sim_message_short" msgid="8340813989586622356">"ನಿಷ್ಪ್ರಯೋಜಕ ಸಿಮ್ ಕಾರ್ಡ್."</string>
+ <string name="keyguard_permanent_disabled_sim_instructions" msgid="5892940909699723544">"ನಿಮ್ಮ ಸಿಮ್ ಕಾರ್ಡ್ ಅನ್ನು ಶಾಶ್ವತವಾಗಿ ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಲಾಗಿದೆ.\n ಮತ್ತೊಂದು ಸಿಮ್ ಕಾರ್ಡ್ಗಾಗಿ ನಿಮ್ಮ ವಯರ್ಲೆಸ್ ಸೇವೆಯ ಪೂರೈಕೆದಾರರನ್ನು ಸಂಪರ್ಕಿಸಿ."</string>
+ <string name="keyguard_sim_locked_message" msgid="6875773413306380902">"ಸಿಮ್ ಕಾರ್ಡ್ ಲಾಕ್ ಮಾಡಲಾಗಿದೆ."</string>
+ <string name="keyguard_sim_puk_locked_message" msgid="3747232467471801633">"ಸಿಮ್ ಕಾರ್ಡ್ ಅನ್ನು PUK-ಲಾಕ್ ಮಾಡಲಾಗಿದೆ."</string>
+ <string name="keyguard_sim_unlock_progress_dialog_message" msgid="7975221805033614426">"ಸಿಮ್ ಕಾರ್ಡ್ ಅನ್ಲಾಕ್ ಮಾಡಲಾಗುತ್ತಿದೆ…"</string>
<string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s.%3$d ರಲ್ಲಿ %2$d ವಿಜೆಟ್."</string>
<string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"ವಿಜೆಟ್ ಸೇರಿಸು."</string>
<string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"ಖಾಲಿ"</string>
@@ -103,20 +103,20 @@
<string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"ಪ್ಯಾಟರ್ನ್ ಅನ್ನು ಮರೆತಿರುವಿರಿ"</string>
<string name="kg_wrong_pattern" msgid="1850806070801358830">"ತಪ್ಪು ಪ್ಯಾಟರ್ನ್"</string>
<string name="kg_wrong_password" msgid="2333281762128113157">"ತಪ್ಪಾದ ಪಾಸ್ವರ್ಡ್"</string>
- <string name="kg_wrong_pin" msgid="1131306510833563801">"ತಪ್ಪಾದ PIN"</string>
+ <string name="kg_wrong_pin" msgid="1131306510833563801">"ತಪ್ಪಾದ ಪಿನ್"</string>
<string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"<xliff:g id="NUMBER">%d</xliff:g> ಸೆಕೆಂಡುಗಳಲ್ಲಿ ಮತ್ತೆ ಪ್ರಯತ್ನಿಸಿ."</string>
<string name="kg_pattern_instructions" msgid="398978611683075868">"ನಿಮ್ಮ ನಮೂನೆಯನ್ನು ಚಿತ್ರಿಸಿ"</string>
- <string name="kg_sim_pin_instructions" msgid="2319508550934557331">"SIM PIN ನಮೂದಿಸಿ"</string>
- <string name="kg_pin_instructions" msgid="2377242233495111557">"PIN ನಮೂದಿಸಿ"</string>
+ <string name="kg_sim_pin_instructions" msgid="2319508550934557331">"ಸಿಮ್ ಪಿನ್ ನಮೂದಿಸಿ"</string>
+ <string name="kg_pin_instructions" msgid="2377242233495111557">"ಪಿನ್ ನಮೂದಿಸಿ"</string>
<string name="kg_password_instructions" msgid="5753646556186936819">"ಪಾಸ್ವರ್ಡ್ ನಮೂದಿಸಿ"</string>
- <string name="kg_puk_enter_puk_hint" msgid="453227143861735537">"ಇದೀಗ SIM ನಿಷ್ಕ್ರಿಯಗೊಂಡಿದೆ. ಮುಂದುವರೆಯಲು PUK ಕೋಡ್ ನಮೂದಿಸಿ. ವಿವರಗಳಿಗಾಗಿ ವಾಹಕವನ್ನು ಸಂಪರ್ಕಿಸಿ."</string>
- <string name="kg_puk_enter_pin_hint" msgid="7871604527429602024">"ಅಗತ್ಯವಿರುವ PIN ಕೋಡ್ ನಮೂದಿಸಿ"</string>
- <string name="kg_enter_confirm_pin_hint" msgid="325676184762529976">"ಬಯಸಿರುವ PIN ಕೋಡ್ ದೃಢೀಕರಿಸಿ"</string>
- <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"SIM ಕಾರ್ಡ್ ಅನ್ಲಾಕ್ ಮಾಡಲಾಗುತ್ತಿದೆ…"</string>
- <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"4 ರಿಂದ 8 ಸಂಖ್ಯೆಗಳಿರುವ PIN ಟೈಪ್ ಮಾಡಿ."</string>
+ <string name="kg_puk_enter_puk_hint" msgid="453227143861735537">"ಇದೀಗ ಸಿಮ್ ನಿಷ್ಕ್ರಿಯಗೊಂಡಿದೆ. ಮುಂದುವರೆಯಲು PUK ಕೋಡ್ ನಮೂದಿಸಿ. ವಿವರಗಳಿಗಾಗಿ ವಾಹಕವನ್ನು ಸಂಪರ್ಕಿಸಿ."</string>
+ <string name="kg_puk_enter_pin_hint" msgid="7871604527429602024">"ಅಗತ್ಯವಿರುವ ಪಿನ್ ಕೋಡ್ ನಮೂದಿಸಿ"</string>
+ <string name="kg_enter_confirm_pin_hint" msgid="325676184762529976">"ಬಯಸಿರುವ ಪಿನ್ ಕೋಡ್ ದೃಢೀಕರಿಸಿ"</string>
+ <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"ಸಿಮ್ ಕಾರ್ಡ್ ಅನ್ಲಾಕ್ ಮಾಡಲಾಗುತ್ತಿದೆ…"</string>
+ <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"4 ರಿಂದ 8 ಸಂಖ್ಯೆಗಳಿರುವ ಪಿನ್ ಟೈಪ್ ಮಾಡಿ."</string>
<string name="kg_invalid_sim_puk_hint" msgid="7553388325654369575">"PUK ಕೋಡ್ 8 ಸಂಖ್ಯೆಗಳು ಅಥವಾ ಅದಕ್ಕಿಂತ ಹೆಚ್ಚಾಗಿರಬೇಕು."</string>
- <string name="kg_invalid_puk" msgid="3638289409676051243">"ಸರಿಯಾದ PUK ಕೋಡ್ ಅನ್ನು ಮರು-ನಮೂದಿಸಿ. ಸತತ ಪ್ರಯತ್ನಗಳು SIM ಅನ್ನು ಶಾಶ್ವತವಾಗಿ ನಿಷ್ಕ್ರಿಯಗೊಳಿಸುತ್ತದೆ."</string>
- <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"PIN ಕೋಡ್ಗಳು ಹೊಂದಾಣಿಕೆಯಾಗುತ್ತಿಲ್ಲ"</string>
+ <string name="kg_invalid_puk" msgid="3638289409676051243">"ಸರಿಯಾದ PUK ಕೋಡ್ ಅನ್ನು ಮರು-ನಮೂದಿಸಿ. ಸತತ ಪ್ರಯತ್ನಗಳು ಸಿಮ್ ಅನ್ನು ಶಾಶ್ವತವಾಗಿ ನಿಷ್ಕ್ರಿಯಗೊಳಿಸುತ್ತದೆ."</string>
+ <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"ಪಿನ್ ಕೋಡ್ಗಳು ಹೊಂದಾಣಿಕೆಯಾಗುತ್ತಿಲ್ಲ"</string>
<string name="kg_login_too_many_attempts" msgid="6486842094005698475">"ಹಲವಾರು ಪ್ಯಾಟರ್ನ್ ಪ್ರಯತ್ನಗಳು"</string>
<string name="kg_login_instructions" msgid="1100551261265506448">"ಅನ್ಲಾಕ್ ಮಾಡಲು, ನಿಮ್ಮ Google ಖಾತೆ ಬಳಸಿಕೊಂಡು ಸೈನ್ ಇನ್ ಮಾಡಿ."</string>
<string name="kg_login_username_hint" msgid="5718534272070920364">"ಬಳಕೆದಾರಹೆಸರು (ಇಮೇಲ್)"</string>
@@ -125,7 +125,7 @@
<string name="kg_login_invalid_input" msgid="5754664119319872197">"ಅಮಾನ್ಯ ಬಳಕೆದಾರಹೆಸರು ಅಥವಾ ಪಾಸ್ವರ್ಡ್."</string>
<string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"ನಿಮ್ಮ ಬಳಕೆದಾರಹೆಸರು ಅಥವಾ ಪಾಸ್ವರ್ಡ್ ಮರೆತಿರುವಿರಾ?\n"<b>"google.com/accounts/recovery"</b>" ಗೆ ಭೇಟಿ ನೀಡಿ."</string>
<string name="kg_login_checking_password" msgid="1052685197710252395">"ಖಾತೆಯನ್ನು ಪರಿಶೀಲಿಸಲಾಗುತ್ತಿದೆ…"</string>
- <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"ನಿಮ್ಮ PIN ಅನ್ನು ನೀವು <xliff:g id="NUMBER_0">%d</xliff:g> ಬಾರಿ ತಪ್ಪಾಗಿ ಟೈಪ್ ಮಾಡಿರುವಿರಿ. \n\n<xliff:g id="NUMBER_1">%d</xliff:g> ಸೆಕೆಂಡುಗಳಲ್ಲಿ ಮತ್ತೆ ಪ್ರಯತ್ನಿಸಿ."</string>
+ <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"ನಿಮ್ಮ ಪಿನ್ ಅನ್ನು ನೀವು <xliff:g id="NUMBER_0">%d</xliff:g> ಬಾರಿ ತಪ್ಪಾಗಿ ಟೈಪ್ ಮಾಡಿರುವಿರಿ. \n\n<xliff:g id="NUMBER_1">%d</xliff:g> ಸೆಕೆಂಡುಗಳಲ್ಲಿ ಮತ್ತೆ ಪ್ರಯತ್ನಿಸಿ."</string>
<string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"ನಿಮ್ಮ ಪಾಸ್ವರ್ಡ್ ಅನ್ನು ನೀವು <xliff:g id="NUMBER_0">%d</xliff:g> ಬಾರಿ ತಪ್ಪಾಗಿ ಟೈಪ್ ಮಾಡಿರುವಿರಿ. \n\n <xliff:g id="NUMBER_1">%d</xliff:g> ಸೆಕೆಂಡುಗಳಲ್ಲಿ ಮತ್ತೆ ಪ್ರಯತ್ನಿಸಿ."</string>
<string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"ನಿಮ್ಮ ಅನ್ಲಾಕ್ ಪ್ಯಾಟರ್ನ್ ಅನ್ನು ನೀವು <xliff:g id="NUMBER_0">%d</xliff:g> ಬಾರಿ ತಪ್ಪಾಗಿ ಚಿತ್ರಿಸಿರುವಿರಿ. \n\n<xliff:g id="NUMBER_1">%d</xliff:g> ಸೆಕೆಂಡುಗಳಲ್ಲಿ ಮತ್ತೆ ಪ್ರಯತ್ನಿಸಿ."</string>
<string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"ಟ್ಯಾಬ್ಲೆಟ್ ಅನ್ಲಾಕ್ ಮಾಡಲು ನೀವು <xliff:g id="NUMBER_0">%d</xliff:g> ಬಾರಿ ತಪ್ಪಾಗಿ ಪ್ರಯತ್ನಿಸಿರುವಿರಿ. <xliff:g id="NUMBER_1">%d</xliff:g> ಕ್ಕೂ ಹೆಚ್ಚಿನ ವಿಫಲ ಪ್ರಯತ್ನಗಳ ಬಳಿಕ, ಟ್ಯಾಬ್ಲೆಟ್ ಅನ್ನು ಫ್ಯಾಕ್ಟರಿ ಡೀಫಾಲ್ಟ್ಗೆ ಮರು ಹೊಂದಿಸಲಾಗುತ್ತದೆ ಮತ್ತು ಎಲ್ಲಾ ಬಳಕೆದಾರರ ಡೇಟಾ ಕಳೆದು ಹೋಗುತ್ತದೆ."</string>
@@ -136,18 +136,18 @@
<string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"ನಿಮ್ಮ ಅನ್ಲಾಕ್ ಪ್ಯಾಟರ್ನ್ ಅನ್ನು ನೀವು <xliff:g id="NUMBER_0">%d</xliff:g> ಬಾರಿ ತಪ್ಪಾಗಿ ಡ್ರಾ ಮಾಡಿರುವಿರಿ. <xliff:g id="NUMBER_1">%d</xliff:g> ಹೆಚ್ಚಿನ ವಿಫಲ ಪ್ರಯತ್ನಗಳ ಬಳಿಕ, ನಿಮ್ಮ ಇಮೇಲ್ ಖಾತೆಯನ್ನು ಬಳಸಿಕೊಂಡು ನಿಮ್ಮ ಫೋನ್ ಅನ್ಲಾಕ್ ಮಾಡುವಂತೆ ನಿಮ್ಮಲ್ಲಿ ಕೇಳಿಕೊಳ್ಳಲಾಗುತ್ತದೆ.\n\n <xliff:g id="NUMBER_2">%d</xliff:g> ಸೆಕೆಂಡುಗಳಲ್ಲಿ ಮತ್ತೆ ಪ್ರಯತ್ನಿಸಿ."</string>
<string name="kg_text_message_separator" product="default" msgid="4160700433287233771">" — "</string>
<string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"ತೆಗೆದುಹಾಕು"</string>
- <string name="kg_password_wrong_pin_code_pukked" msgid="30531039455764924">"SIM PIN ಕೋಡ್ ತಪ್ಪಾಗಿದೆ, ನಿಮ್ಮ ಸಾಧನವನ್ನು ಅನ್ಲಾಕ್ ಮಾಡಲು ನೀವು ಈ ಕೂಡಲೇ ನಿಮ್ಮ ವಾಹಕವನ್ನು ಸಂಪರ್ಕಿಸಬೇಕು."</string>
+ <string name="kg_password_wrong_pin_code_pukked" msgid="30531039455764924">"ಸಿಮ್ ಪಿನ್ ಕೋಡ್ ತಪ್ಪಾಗಿದೆ, ನಿಮ್ಮ ಸಾಧನವನ್ನು ಅನ್ಲಾಕ್ ಮಾಡಲು ನೀವು ಈ ಕೂಡಲೇ ನಿಮ್ಮ ವಾಹಕವನ್ನು ಸಂಪರ್ಕಿಸಬೇಕು."</string>
<plurals name="kg_password_wrong_pin_code">
- <item quantity="one" msgid="8134313997799638254">"ತಪ್ಪಾಗಿರುವ SIM PIN ಕೋಡ್, ನಿಮ್ಮ ಸಾಧನವನ್ನು ಅನ್ಲಾಕ್ ಮಾಡುವ ಸಲುವಾಗಿ ನಿಮ್ಮ ವಾಹಕವನ್ನು ನೀವು ಸಂಪರ್ಕಿಸುವುದಕ್ಕೂ ಮೊದಲು ನಿಮ್ಮಲ್ಲಿ <xliff:g id="NUMBER">%d</xliff:g> ಪ್ರಯತ್ನಗಳು ಬಾಕಿ ಉಳಿದಿವೆ."</item>
- <item quantity="other" msgid="2215723361575359486">"ತಪ್ಪಾಗಿರುವ SIM PIN ಕೋಡ್, ನಿಮ್ಮಲ್ಲಿ <xliff:g id="NUMBER">%d</xliff:g> ಪ್ರಯತ್ನಗಳು ಬಾಕಿ ಉಳಿದಿವೆ."</item>
+ <item quantity="one" msgid="8134313997799638254">"ತಪ್ಪಾಗಿರುವ ಸಿಮ್ ಪಿನ್ ಕೋಡ್, ನಿಮ್ಮ ಸಾಧನವನ್ನು ಅನ್ಲಾಕ್ ಮಾಡುವ ಸಲುವಾಗಿ ನಿಮ್ಮ ವಾಹಕವನ್ನು ನೀವು ಸಂಪರ್ಕಿಸುವುದಕ್ಕೂ ಮೊದಲು ನಿಮ್ಮಲ್ಲಿ <xliff:g id="NUMBER">%d</xliff:g> ಪ್ರಯತ್ನಗಳು ಬಾಕಿ ಉಳಿದಿವೆ."</item>
+ <item quantity="other" msgid="2215723361575359486">"ತಪ್ಪಾಗಿರುವ ಸಿಮ್ ಪಿನ್ ಕೋಡ್, ನಿಮ್ಮಲ್ಲಿ <xliff:g id="NUMBER">%d</xliff:g> ಪ್ರಯತ್ನಗಳು ಬಾಕಿ ಉಳಿದಿವೆ."</item>
</plurals>
- <string name="kg_password_wrong_puk_code_dead" msgid="7077536808291316208">"SIM ನಿಷ್ಪ್ರಯೋಜಕವಾಗಿದೆ. ನಿಮ್ಮ ವಾಹಕವನ್ನು ಸಂಪರ್ಕಿಸಿ."</string>
+ <string name="kg_password_wrong_puk_code_dead" msgid="7077536808291316208">"ಸಿಮ್ ನಿಷ್ಪ್ರಯೋಜಕವಾಗಿದೆ. ನಿಮ್ಮ ವಾಹಕವನ್ನು ಸಂಪರ್ಕಿಸಿ."</string>
<plurals name="kg_password_wrong_puk_code">
- <item quantity="one" msgid="3256893607561060649">"ತಪ್ಪಾಗಿರುವ SIM PUK ಕೋಡ್, SIM ಶಾಶ್ವತವಾಗಿ ನಿಷ್ಪ್ರಯೋಜಕವಾಗುವುದಕ್ಕೂ ಮೊದಲು ನಿಮ್ಮಲ್ಲಿ <xliff:g id="NUMBER">%d</xliff:g> ಪ್ರಯತ್ನ ಬಾಕಿ ಉಳಿದಿದೆ."</item>
- <item quantity="other" msgid="5477305226026342036">"ತಪ್ಪಾಗಿರುವ SIM PUK ಕೋಡ್, SIM ಶಾಶ್ವತವಾಗಿ ನಿಷ್ಪ್ರಯೋಜಕವಾಗುವುದಕ್ಕೂ ಮೊದಲು ನಿಮ್ಮಲ್ಲಿ <xliff:g id="NUMBER">%d</xliff:g> ಪ್ರಯತ್ನಗಳು ಬಾಕಿ ಉಳಿದಿವೆ."</item>
+ <item quantity="one" msgid="3256893607561060649">"ತಪ್ಪಾಗಿರುವ ಸಿಮ್ PUK ಕೋಡ್, ಸಿಮ್ ಶಾಶ್ವತವಾಗಿ ನಿಷ್ಪ್ರಯೋಜಕವಾಗುವುದಕ್ಕೂ ಮೊದಲು ನಿಮ್ಮಲ್ಲಿ <xliff:g id="NUMBER">%d</xliff:g> ಪ್ರಯತ್ನ ಬಾಕಿ ಉಳಿದಿದೆ."</item>
+ <item quantity="other" msgid="5477305226026342036">"ತಪ್ಪಾಗಿರುವ ಸಿಮ್ PUK ಕೋಡ್, ಸಿಮ್ ಶಾಶ್ವತವಾಗಿ ನಿಷ್ಪ್ರಯೋಜಕವಾಗುವುದಕ್ಕೂ ಮೊದಲು ನಿಮ್ಮಲ್ಲಿ <xliff:g id="NUMBER">%d</xliff:g> ಪ್ರಯತ್ನಗಳು ಬಾಕಿ ಉಳಿದಿವೆ."</item>
</plurals>
- <string name="kg_password_pin_failed" msgid="6268288093558031564">"SIM PIN ಕಾರ್ಯಾಚರಣೆ ವಿಫಲಗೊಂಡಿದೆ!"</string>
- <string name="kg_password_puk_failed" msgid="2838824369502455984">"SIM PUK ಕಾರ್ಯಾಚರಣೆ ವಿಫಲಗೊಂಡಿದೆ!"</string>
+ <string name="kg_password_pin_failed" msgid="6268288093558031564">"ಸಿಮ್ ಪಿನ್ ಕಾರ್ಯಾಚರಣೆ ವಿಫಲಗೊಂಡಿದೆ!"</string>
+ <string name="kg_password_puk_failed" msgid="2838824369502455984">"ಸಿಮ್ PUK ಕಾರ್ಯಾಚರಣೆ ವಿಫಲಗೊಂಡಿದೆ!"</string>
<string name="kg_pin_accepted" msgid="1448241673570020097">"ಕೋಡ್ ಅಂಗೀಕೃತವಾಗಿದೆ!"</string>
<string name="keyguard_transport_prev_description" msgid="8229108430245669854">"ಹಿಂದಿನ ಹಾಡಿನ ಬಟನ್"</string>
<string name="keyguard_transport_next_description" msgid="4299258300283778305">"ಮುಂದಿನ ಹಾಡು ಬಟನ್"</string>
diff --git a/packages/Keyguard/res/values-ml-rIN/strings.xml b/packages/Keyguard/res/values-ml-rIN/strings.xml
index 8de171c..0dd0ea8 100644
--- a/packages/Keyguard/res/values-ml-rIN/strings.xml
+++ b/packages/Keyguard/res/values-ml-rIN/strings.xml
@@ -22,13 +22,13 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_name" msgid="719438068451601849">"കീഗാർഡ്"</string>
<string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"പിൻ കോഡ് ടൈപ്പുചെയ്യുക"</string>
- <string name="keyguard_password_enter_puk_code" msgid="3035856550289724338">"SIM PUK-യും പുതിയ PIN കോഡും ടൈപ്പുചെയ്യുക"</string>
- <string name="keyguard_password_enter_puk_prompt" msgid="1801941051094974609">"SIM PUK കോഡ്"</string>
- <string name="keyguard_password_enter_pin_prompt" msgid="3201151840570492538">"പുതിയ SIM PIN കോഡ്"</string>
+ <string name="keyguard_password_enter_puk_code" msgid="3035856550289724338">"സിം PUK-യും പുതിയ പിൻ കോഡും ടൈപ്പുചെയ്യുക"</string>
+ <string name="keyguard_password_enter_puk_prompt" msgid="1801941051094974609">"സിം PUK കോഡ്"</string>
+ <string name="keyguard_password_enter_pin_prompt" msgid="3201151840570492538">"പുതിയ സിം പിൻ കോഡ്"</string>
<string name="keyguard_password_entry_touch_hint" msgid="7858547464982981384"><font size="17">"പാസ്വേഡ് ടൈപ്പുചെയ്യുന്നതിന് സ്പർശിക്കുക"</font></string>
<string name="keyguard_password_enter_password_code" msgid="1054721668279049780">"അൺലോക്കുചെയ്യുന്നതിന് പാസ്വേഡ് ടൈപ്പുചെയ്യുക"</string>
<string name="keyguard_password_enter_pin_password_code" msgid="6391755146112503443">"അൺലോക്കുചെയ്യുന്നതിന് പിൻ ടൈപ്പുചെയ്യുക"</string>
- <string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"PIN കോഡ് തെറ്റാണ്."</string>
+ <string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"പിൻ കോഡ് തെറ്റാണ്."</string>
<string name="keyguard_label_text" msgid="861796461028298424">"അൺലോക്ക് ചെയ്യുന്നതിന് മെനു, 0 എന്നിവ അമർത്തുക."</string>
<string name="faceunlock_multiple_failures" msgid="754137583022792429">"മുഖം തിരിച്ചറിഞ്ഞുള്ള അൺലോക്ക് ശ്രമങ്ങളുടെ പരമാവധി കഴിഞ്ഞു"</string>
<string name="keyguard_charged" msgid="3272223906073492454">"ചാർജ്ജുചെയ്തു"</string>
@@ -36,16 +36,16 @@
<string name="keyguard_low_battery" msgid="8143808018719173859">"നിങ്ങളുടെ ചാർജ്ജർ കണക്റ്റുചെയ്യുക."</string>
<string name="keyguard_instructions_when_pattern_disabled" msgid="1332288268600329841">"അൺലോക്കുചെയ്യാൻ മെനു അമർത്തുക"</string>
<string name="keyguard_network_locked_message" msgid="9169717779058037168">"നെറ്റ്വർക്ക് ലോക്കുചെയ്തു"</string>
- <string name="keyguard_missing_sim_message_short" msgid="494980561304211931">"SIM കാർഡൊന്നുമില്ല"</string>
- <string name="keyguard_missing_sim_message" product="tablet" msgid="1445849005909260039">"ടാബ്ലെറ്റിൽ SIM കാർഡൊന്നുമില്ല."</string>
- <string name="keyguard_missing_sim_message" product="default" msgid="3481110395508637643">"ഫോണിൽ SIM കാർഡൊന്നുമില്ല."</string>
- <string name="keyguard_missing_sim_instructions" msgid="5210891509995942250">"ഒരു SIM കാർഡ് ചേർക്കുക."</string>
- <string name="keyguard_missing_sim_instructions_long" msgid="5968985489463870358">"SIM കാർഡ് കാണുന്നില്ല അല്ലെങ്കിൽ റീഡുചെയ്യാനായില്ല. ഒരു SIM കാർഡ് ചേർക്കുക."</string>
- <string name="keyguard_permanent_disabled_sim_message_short" msgid="8340813989586622356">"ഉപയോഗശൂന്യമായ SIM കാർഡ്."</string>
- <string name="keyguard_permanent_disabled_sim_instructions" msgid="5892940909699723544">"നിങ്ങളുടെ SIM കാർഡ് ശാശ്വതമായി പ്രവർത്തനരഹിതമാക്കി.\n മറ്റൊരു SIM കാർഡിനായി നിങ്ങളുടെ വയർലെസ് സേവന ദാതാവിനെ ബന്ധപ്പെടുക."</string>
- <string name="keyguard_sim_locked_message" msgid="6875773413306380902">"SIM കാർഡ് ലോക്കുചെയ്തു."</string>
- <string name="keyguard_sim_puk_locked_message" msgid="3747232467471801633">"SIM കാർഡ് PUK-ലോക്ക് ചെയ്തതാണ്."</string>
- <string name="keyguard_sim_unlock_progress_dialog_message" msgid="7975221805033614426">"SIM കാർഡ് അൺലോക്കുചെയ്യുന്നു…"</string>
+ <string name="keyguard_missing_sim_message_short" msgid="494980561304211931">"സിം കാർഡൊന്നുമില്ല"</string>
+ <string name="keyguard_missing_sim_message" product="tablet" msgid="1445849005909260039">"ടാബ്ലെറ്റിൽ സിം കാർഡൊന്നുമില്ല."</string>
+ <string name="keyguard_missing_sim_message" product="default" msgid="3481110395508637643">"ഫോണിൽ സിം കാർഡൊന്നുമില്ല."</string>
+ <string name="keyguard_missing_sim_instructions" msgid="5210891509995942250">"ഒരു സിം കാർഡ് ചേർക്കുക."</string>
+ <string name="keyguard_missing_sim_instructions_long" msgid="5968985489463870358">"സിം കാർഡ് കാണുന്നില്ല അല്ലെങ്കിൽ റീഡുചെയ്യാനായില്ല. ഒരു സിം കാർഡ് ചേർക്കുക."</string>
+ <string name="keyguard_permanent_disabled_sim_message_short" msgid="8340813989586622356">"ഉപയോഗശൂന്യമായ സിം കാർഡ്."</string>
+ <string name="keyguard_permanent_disabled_sim_instructions" msgid="5892940909699723544">"നിങ്ങളുടെ സിം കാർഡ് ശാശ്വതമായി പ്രവർത്തനരഹിതമാക്കി.\n മറ്റൊരു സിം കാർഡിനായി നിങ്ങളുടെ വയർലെസ് സേവന ദാതാവിനെ ബന്ധപ്പെടുക."</string>
+ <string name="keyguard_sim_locked_message" msgid="6875773413306380902">"സിം കാർഡ് ലോക്കുചെയ്തു."</string>
+ <string name="keyguard_sim_puk_locked_message" msgid="3747232467471801633">"സിം കാർഡ് PUK-ലോക്ക് ചെയ്തതാണ്."</string>
+ <string name="keyguard_sim_unlock_progress_dialog_message" msgid="7975221805033614426">"സിം കാർഡ് അൺലോക്കുചെയ്യുന്നു…"</string>
<string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. വിജറ്റ് %2$d / %3$d."</string>
<string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"വിജറ്റ് ചേർക്കുക."</string>
<string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"ശൂന്യം"</string>
@@ -103,20 +103,20 @@
<string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"പാറ്റേൺ മറന്നു"</string>
<string name="kg_wrong_pattern" msgid="1850806070801358830">"പാറ്റേൺ തെറ്റാണ്"</string>
<string name="kg_wrong_password" msgid="2333281762128113157">"പാസ്വേഡ് തെറ്റാണ്"</string>
- <string name="kg_wrong_pin" msgid="1131306510833563801">"PIN തെറ്റാണ്"</string>
+ <string name="kg_wrong_pin" msgid="1131306510833563801">"പിൻ തെറ്റാണ്"</string>
<string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"<xliff:g id="NUMBER">%d</xliff:g> സെക്കൻഡിനുള്ളിൽ വീണ്ടും ശ്രമിക്കുക."</string>
<string name="kg_pattern_instructions" msgid="398978611683075868">"നിങ്ങളുടെ പാറ്റേൺ വരയ്ക്കുക"</string>
- <string name="kg_sim_pin_instructions" msgid="2319508550934557331">"SIM PIN നൽകുക"</string>
- <string name="kg_pin_instructions" msgid="2377242233495111557">"PIN നൽകുക"</string>
+ <string name="kg_sim_pin_instructions" msgid="2319508550934557331">"സിം പിൻ നൽകുക"</string>
+ <string name="kg_pin_instructions" msgid="2377242233495111557">"പിൻ നൽകുക"</string>
<string name="kg_password_instructions" msgid="5753646556186936819">"പാസ്വേഡ് നൽകുക"</string>
- <string name="kg_puk_enter_puk_hint" msgid="453227143861735537">"SIM ഇപ്പോൾ പ്രവർത്തനരഹിതമാക്കി. തുടരുന്നതിന് PUK കോഡ് നൽകുക. വിശദാംശങ്ങൾക്ക് കാരിയറെ ബന്ധപ്പെടുക."</string>
- <string name="kg_puk_enter_pin_hint" msgid="7871604527429602024">"താൽപ്പര്യപ്പെട്ട PIN കോഡ് നൽകുക"</string>
- <string name="kg_enter_confirm_pin_hint" msgid="325676184762529976">"താൽപ്പര്യപ്പെട്ട PIN കോഡ് സ്ഥിരീകരിക്കുക"</string>
- <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"SIM കാർഡ് അൺലോക്കുചെയ്യുന്നു…"</string>
- <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"4 മുതൽ 8 വരെ അക്കങ്ങളുള്ള ഒരു PIN നൽകുക."</string>
+ <string name="kg_puk_enter_puk_hint" msgid="453227143861735537">"സിം ഇപ്പോൾ പ്രവർത്തനരഹിതമാക്കി. തുടരുന്നതിന് PUK കോഡ് നൽകുക. വിശദാംശങ്ങൾക്ക് കാരിയറെ ബന്ധപ്പെടുക."</string>
+ <string name="kg_puk_enter_pin_hint" msgid="7871604527429602024">"താൽപ്പര്യപ്പെട്ട പിൻ കോഡ് നൽകുക"</string>
+ <string name="kg_enter_confirm_pin_hint" msgid="325676184762529976">"താൽപ്പര്യപ്പെട്ട പിൻ കോഡ് സ്ഥിരീകരിക്കുക"</string>
+ <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"സിം കാർഡ് അൺലോക്കുചെയ്യുന്നു…"</string>
+ <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"4 മുതൽ 8 വരെ അക്കങ്ങളുള്ള ഒരു പിൻ നൽകുക."</string>
<string name="kg_invalid_sim_puk_hint" msgid="7553388325654369575">"PUK കോഡിൽ 8 അല്ലെങ്കിൽ അതിലധികം സംഖ്യകൾ ഉണ്ടായിരിക്കണം."</string>
- <string name="kg_invalid_puk" msgid="3638289409676051243">"ശരിയായ PUK കോഡ് വീണ്ടും നൽകുക. ആവർത്തിച്ചുള്ള ശ്രമങ്ങൾ SIM ശാശ്വതമായി പ്രവർത്തനരഹിതമാക്കും."</string>
- <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"PIN കോഡുകൾ പൊരുത്തപ്പെടുന്നില്ല"</string>
+ <string name="kg_invalid_puk" msgid="3638289409676051243">"ശരിയായ PUK കോഡ് വീണ്ടും നൽകുക. ആവർത്തിച്ചുള്ള ശ്രമങ്ങൾ സിം ശാശ്വതമായി പ്രവർത്തനരഹിതമാക്കും."</string>
+ <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"പിൻ കോഡുകൾ പൊരുത്തപ്പെടുന്നില്ല"</string>
<string name="kg_login_too_many_attempts" msgid="6486842094005698475">"വളരെയധികം പാറ്റേൺ ശ്രമങ്ങൾ"</string>
<string name="kg_login_instructions" msgid="1100551261265506448">"അൺലോക്കുചെയ്യുന്നതിന്, നിങ്ങളുടെ Google അക്കൗണ്ട് ഉപയോഗിച്ച് സൈൻ ഇൻ ചെയ്യുക."</string>
<string name="kg_login_username_hint" msgid="5718534272070920364">"ഉപയോക്തൃനാമം (ഇമെയിൽ)"</string>
@@ -125,7 +125,7 @@
<string name="kg_login_invalid_input" msgid="5754664119319872197">"ഉപയോക്തൃനാമമോ പാസ്വേഡോ അസാധുവാണ്."</string>
<string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"നിങ്ങളുടെ ഉപയോക്തൃനാമമോ പാസ്വേഡോ മറന്നുപോയോ?\n"<b>"google.com/accounts/recovery"</b>" സന്ദർശിക്കുക."</string>
<string name="kg_login_checking_password" msgid="1052685197710252395">"അക്കൗണ്ട് പരിശോധിക്കുന്നു…"</string>
- <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"നിങ്ങളുടെ PIN <xliff:g id="NUMBER_0">%d</xliff:g> തവണ തെറ്റായി ടൈപ്പുചെയ്തു. \n\n<xliff:g id="NUMBER_1">%d</xliff:g> സെക്കൻഡിനുള്ളിൽ വീണ്ടും ശ്രമിക്കുക."</string>
+ <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"നിങ്ങളുടെ പിൻ <xliff:g id="NUMBER_0">%d</xliff:g> തവണ തെറ്റായി ടൈപ്പുചെയ്തു. \n\n<xliff:g id="NUMBER_1">%d</xliff:g> സെക്കൻഡിനുള്ളിൽ വീണ്ടും ശ്രമിക്കുക."</string>
<string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"നിങ്ങളുടെ പാസ്വേഡ് <xliff:g id="NUMBER_0">%d</xliff:g> തവണ തെറ്റായി ടൈപ്പുചെയ്തു. \n\n<xliff:g id="NUMBER_1">%d</xliff:g> സെക്കൻഡിനുള്ളിൽ വീണ്ടും ശ്രമിക്കുക."</string>
<string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"നിങ്ങളുടെ പാറ്റേൺ <xliff:g id="NUMBER_0">%d</xliff:g> തവണ തെറ്റായി വരച്ചു. \n\n<xliff:g id="NUMBER_1">%d</xliff:g> സെക്കൻഡിനുള്ളിൽ വീണ്ടും ശ്രമിക്കുക."</string>
<string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"നിങ്ങൾ ഫോൺ അൺലോക്കുചെയ്യാൻ തവണ <xliff:g id="NUMBER_0">%d</xliff:g> തെറ്റായി ശ്രമിച്ചു. <xliff:g id="NUMBER_1">%d</xliff:g> ശ്രമങ്ങൾ കൂടി വിജയിച്ചില്ലെങ്കിൽ, ടാബ്ലെറ്റ് ഫാക്ടറി ഡിഫോൾട്ടിലേക്ക് പുനഃസജ്ജികരിക്കുകയും ഉപയോക്തൃ ഡാറ്റയെല്ലാം നഷ്ടപ്പെടുകയും ചെയ്യും."</string>
@@ -136,18 +136,18 @@
<string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"നിങ്ങളുടെ അൺലോക്ക് പാറ്റേൺ <xliff:g id="NUMBER_0">%d</xliff:g> തവണ തെറ്റായി വരച്ചു. <xliff:g id="NUMBER_1">%d</xliff:g> ശ്രമങ്ങൾ കൂടി വിജയിച്ചില്ലെങ്കിൽ, ഒരു ഇമെയിൽ അക്കൗണ്ട് ഉപയോഗിച്ച് ഫോൺ അൺലോക്ക് ചെയ്യാൻ നിങ്ങളോട് ആവശ്യപ്പെടും.\n\n <xliff:g id="NUMBER_2">%d</xliff:g> സെക്കൻഡിനുള്ള വീണ്ടും ശ്രമിക്കുക."</string>
<string name="kg_text_message_separator" product="default" msgid="4160700433287233771">" — "</string>
<string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"നീക്കംചെയ്യുക"</string>
- <string name="kg_password_wrong_pin_code_pukked" msgid="30531039455764924">"SIM PIN കോഡ് തെറ്റാണ്, നിങ്ങളുടെ ഉപകരണം അൺലോക്കുചെയ്യാൻ ഇപ്പോൾ നിങ്ങളുടെ കാരിയറുമായി ബന്ധപ്പെടണം."</string>
+ <string name="kg_password_wrong_pin_code_pukked" msgid="30531039455764924">"സിം പിൻ കോഡ് തെറ്റാണ്, നിങ്ങളുടെ ഉപകരണം അൺലോക്കുചെയ്യാൻ ഇപ്പോൾ നിങ്ങളുടെ കാരിയറുമായി ബന്ധപ്പെടണം."</string>
<plurals name="kg_password_wrong_pin_code">
- <item quantity="one" msgid="8134313997799638254">"തെറ്റായ SIM PIN കോഡ്, നിങ്ങളുടെ ഉപകരണം അൺലോക്കുചെയ്യാൻ സേവനദാതാവുമായി ബന്ധപ്പെടുന്നതിന് മുമ്പായി നിങ്ങൾക്ക് <xliff:g id="NUMBER">%d</xliff:g> ശ്രമം കൂടി ബാക്കിയുണ്ട്."</item>
- <item quantity="other" msgid="2215723361575359486">"തെറ്റായ SIM PIN കോഡ്, നിങ്ങൾക്ക് <xliff:g id="NUMBER">%d</xliff:g> ശ്രമങ്ങൾ കൂടി ബാക്കിയുണ്ട്."</item>
+ <item quantity="one" msgid="8134313997799638254">"തെറ്റായ സിം പിൻ കോഡ്, നിങ്ങളുടെ ഉപകരണം അൺലോക്കുചെയ്യാൻ സേവനദാതാവുമായി ബന്ധപ്പെടുന്നതിന് മുമ്പായി നിങ്ങൾക്ക് <xliff:g id="NUMBER">%d</xliff:g> ശ്രമം കൂടി ബാക്കിയുണ്ട്."</item>
+ <item quantity="other" msgid="2215723361575359486">"തെറ്റായ സിം പിൻ കോഡ്, നിങ്ങൾക്ക് <xliff:g id="NUMBER">%d</xliff:g> ശ്രമങ്ങൾ കൂടി ബാക്കിയുണ്ട്."</item>
</plurals>
- <string name="kg_password_wrong_puk_code_dead" msgid="7077536808291316208">"SIM ഉപയോഗശൂന്യമാണ്. നിങ്ങളുടെ കാരിയറെ ബന്ധപ്പെടുക."</string>
+ <string name="kg_password_wrong_puk_code_dead" msgid="7077536808291316208">"സിം ഉപയോഗശൂന്യമാണ്. നിങ്ങളുടെ കാരിയറെ ബന്ധപ്പെടുക."</string>
<plurals name="kg_password_wrong_puk_code">
- <item quantity="one" msgid="3256893607561060649">"തെറ്റായ SIM PUK കോഡ്, SIM ശാശ്വതമായി ഉപയോഗശൂന്യമാകുന്നതിന് മുമ്പായി നിങ്ങൾക്ക് <xliff:g id="NUMBER">%d</xliff:g> ശ്രമം കൂടി ബാക്കിയുണ്ട്."</item>
- <item quantity="other" msgid="5477305226026342036">"തെറ്റായ SIM PUK കോഡ്, SIM ശാശ്വതമായി ഉപയോഗശൂന്യമാകുന്നതിന് മുമ്പായി നിങ്ങൾക്ക് <xliff:g id="NUMBER">%d</xliff:g> ശ്രമങ്ങൾ കൂടി ബാക്കിയുണ്ട്."</item>
+ <item quantity="one" msgid="3256893607561060649">"തെറ്റായ സിം PUK കോഡ്, സിം ശാശ്വതമായി ഉപയോഗശൂന്യമാകുന്നതിന് മുമ്പായി നിങ്ങൾക്ക് <xliff:g id="NUMBER">%d</xliff:g> ശ്രമം കൂടി ബാക്കിയുണ്ട്."</item>
+ <item quantity="other" msgid="5477305226026342036">"തെറ്റായ സിം PUK കോഡ്, സിം ശാശ്വതമായി ഉപയോഗശൂന്യമാകുന്നതിന് മുമ്പായി നിങ്ങൾക്ക് <xliff:g id="NUMBER">%d</xliff:g> ശ്രമങ്ങൾ കൂടി ബാക്കിയുണ്ട്."</item>
</plurals>
- <string name="kg_password_pin_failed" msgid="6268288093558031564">"SIM PIN പ്രവർത്തനം പരാജയപ്പെട്ടു!"</string>
- <string name="kg_password_puk_failed" msgid="2838824369502455984">"SIM PUK പ്രവർത്തനം പരാജയപ്പെട്ടു!"</string>
+ <string name="kg_password_pin_failed" msgid="6268288093558031564">"സിം പിൻ പ്രവർത്തനം പരാജയപ്പെട്ടു!"</string>
+ <string name="kg_password_puk_failed" msgid="2838824369502455984">"സിം PUK പ്രവർത്തനം പരാജയപ്പെട്ടു!"</string>
<string name="kg_pin_accepted" msgid="1448241673570020097">"കോഡ് അംഗികരിച്ചു!"</string>
<string name="keyguard_transport_prev_description" msgid="8229108430245669854">"മുമ്പത്തെ ട്രാക്ക് ബട്ടൺ"</string>
<string name="keyguard_transport_next_description" msgid="4299258300283778305">"പുതിയ ട്രാക്ക് ബട്ടൺ"</string>
diff --git a/packages/Keyguard/res/values-mr-rIN/strings.xml b/packages/Keyguard/res/values-mr-rIN/strings.xml
index 4265305..6611413 100644
--- a/packages/Keyguard/res/values-mr-rIN/strings.xml
+++ b/packages/Keyguard/res/values-mr-rIN/strings.xml
@@ -21,14 +21,14 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_name" msgid="719438068451601849">"कीगार्ड"</string>
- <string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"PIN कोड टाइप करा"</string>
+ <string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"पिन कोड टाइप करा"</string>
<string name="keyguard_password_enter_puk_code" msgid="3035856550289724338">"सिम PUK आणि नवीन पिन कोड टाइप करा"</string>
<string name="keyguard_password_enter_puk_prompt" msgid="1801941051094974609">"सिम PUK कोड"</string>
<string name="keyguard_password_enter_pin_prompt" msgid="3201151840570492538">"नवीन सिम पिन कोड"</string>
<string name="keyguard_password_entry_touch_hint" msgid="7858547464982981384"><font size="17">"संकेतशब्द टाइप करण्यासाठी स्पर्श करा"</font></string>
<string name="keyguard_password_enter_password_code" msgid="1054721668279049780">"अनलॉक करण्यासाठी संकेतशब्द टाइप करा"</string>
- <string name="keyguard_password_enter_pin_password_code" msgid="6391755146112503443">"अनलॉक करण्यासाठी PIN टाइप करा"</string>
- <string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"अयोग्य PIN कोड."</string>
+ <string name="keyguard_password_enter_pin_password_code" msgid="6391755146112503443">"अनलॉक करण्यासाठी पिन टाइप करा"</string>
+ <string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"अयोग्य पिन कोड."</string>
<string name="keyguard_label_text" msgid="861796461028298424">"अनलॉक करण्यासाठी, मेनू दाबा नंतर 0."</string>
<string name="faceunlock_multiple_failures" msgid="754137583022792429">"कमाल चेहरा अनलॉक प्रयत्न ओलांडले"</string>
<string name="keyguard_charged" msgid="3272223906073492454">"चार्ज झाली"</string>
@@ -103,20 +103,20 @@
<string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"नमुना विसरलात"</string>
<string name="kg_wrong_pattern" msgid="1850806070801358830">"चुकीचा नमुना"</string>
<string name="kg_wrong_password" msgid="2333281762128113157">"चुकीचा संकेतशब्द"</string>
- <string name="kg_wrong_pin" msgid="1131306510833563801">"चुकीचा PIN"</string>
+ <string name="kg_wrong_pin" msgid="1131306510833563801">"चुकीचा पिन"</string>
<string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"<xliff:g id="NUMBER">%d</xliff:g> सेकंदांमध्ये पुन्हा प्रयत्न करा."</string>
<string name="kg_pattern_instructions" msgid="398978611683075868">"आपला नमुना काढा"</string>
- <string name="kg_sim_pin_instructions" msgid="2319508550934557331">"सिम PIN प्रविष्ट करा"</string>
- <string name="kg_pin_instructions" msgid="2377242233495111557">"PIN प्रविष्ट करा"</string>
+ <string name="kg_sim_pin_instructions" msgid="2319508550934557331">"सिम पिन प्रविष्ट करा"</string>
+ <string name="kg_pin_instructions" msgid="2377242233495111557">"पिन प्रविष्ट करा"</string>
<string name="kg_password_instructions" msgid="5753646556186936819">"संकेतशब्द प्रविष्ट करा"</string>
<string name="kg_puk_enter_puk_hint" msgid="453227143861735537">"सिम आता अक्षम केले आहे. सुरु ठेवण्यासाठी PUK कोड प्रविष्ट करा. तपशीलांसाठी वाहकाशी संपर्क साधा."</string>
- <string name="kg_puk_enter_pin_hint" msgid="7871604527429602024">"इच्छित PIN कोड प्रविष्ट करा"</string>
- <string name="kg_enter_confirm_pin_hint" msgid="325676184762529976">"इच्छित PIN कोड ची पुष्टी करा"</string>
+ <string name="kg_puk_enter_pin_hint" msgid="7871604527429602024">"इच्छित पिन कोड प्रविष्ट करा"</string>
+ <string name="kg_enter_confirm_pin_hint" msgid="325676184762529976">"इच्छित पिन कोड ची पुष्टी करा"</string>
<string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"सिम कार्ड अनलॉक करत आहे…"</string>
- <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"4 ते 8 अंक असलेला PIN टाइप करा."</string>
+ <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"4 ते 8 अंक असलेला पिन टाइप करा."</string>
<string name="kg_invalid_sim_puk_hint" msgid="7553388325654369575">"PUK कोड 8 अंकी किंवा त्यापेक्षा अधिकचा असावा."</string>
<string name="kg_invalid_puk" msgid="3638289409676051243">"योग्य PUK कोड पुन्हा-प्रविष्ट करा. परत प्रयत्न करणे सिम कायमचे अक्षम करेल."</string>
- <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"PIN कोड जुळत नाहीत"</string>
+ <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"पिन कोड जुळत नाहीत"</string>
<string name="kg_login_too_many_attempts" msgid="6486842094005698475">"बरेच नमुना प्रयत्न"</string>
<string name="kg_login_instructions" msgid="1100551261265506448">"अनलॉक करण्यासाठी, आपल्या Google खात्यासह साइन इन करा."</string>
<string name="kg_login_username_hint" msgid="5718534272070920364">"वापरकर्तानाव (ईमेल)"</string>
@@ -125,7 +125,7 @@
<string name="kg_login_invalid_input" msgid="5754664119319872197">"अवैध वापरकर्तानाव किंवा संकेतशब्द."</string>
<string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"आपले वापरकर्तानाव किंवा संकेतशब्द विसरलात?\n "<b>"google.com/accounts/recovery"</b>" ला भेट द्या."</string>
<string name="kg_login_checking_password" msgid="1052685197710252395">"खाते तपासत आहे…"</string>
- <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"आपण आपला PIN <xliff:g id="NUMBER_0">%d</xliff:g> वेळा अयोग्यरितीने टाइप केला आहे. \n\n <xliff:g id="NUMBER_1">%d</xliff:g> सेकंदांमध्ये पुन्हा प्रयत्न करा."</string>
+ <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"आपण आपला पिन <xliff:g id="NUMBER_0">%d</xliff:g> वेळा अयोग्यरितीने टाइप केला आहे. \n\n <xliff:g id="NUMBER_1">%d</xliff:g> सेकंदांमध्ये पुन्हा प्रयत्न करा."</string>
<string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"आपण आपला संकेतशब्द <xliff:g id="NUMBER_0">%d</xliff:g> वेळा अयोग्यरितीने टाइप केला आहे. \n\n <xliff:g id="NUMBER_1">%d</xliff:g> सेकंदांमध्ये पुन्हा प्रयत्न करा."</string>
<string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"आपण आपला अनलॉक नमुना <xliff:g id="NUMBER_0">%d</xliff:g> वेळा अयोग्यरितीने काढला आहे. \n\n <xliff:g id="NUMBER_1">%d</xliff:g> सेकंदांमध्ये पुन्हा प्रयत्न करा."</string>
<string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"आपण <xliff:g id="NUMBER_0">%d</xliff:g> वेळा टॅब्लेट अनलॉक करण्याचा अयोग्यपणे प्रयत्न केला. <xliff:g id="NUMBER_1">%d</xliff:g> आणखी अयशस्वी प्रयत्नांनंतर, टॅब्लेट फॅक्टरी डीफॉल्टवर रीसेट केला जाईल आणि वापरकर्ता डेटा गमावेल."</string>
diff --git a/packages/Keyguard/res/values-my-rMM/strings.xml b/packages/Keyguard/res/values-my-rMM/strings.xml
index b3ebaad..979b36e 100644
--- a/packages/Keyguard/res/values-my-rMM/strings.xml
+++ b/packages/Keyguard/res/values-my-rMM/strings.xml
@@ -20,22 +20,22 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="719438068451601849">"သော့ချက် စောင့်ပေးသူ"</string>
- <string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"PIN ကုဒ် ရိုက်ထည့်ပါ"</string>
+ <string name="app_name" msgid="719438068451601849">"သော့ချက် စောင့်ပေးသူ"</string>
+ <string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"PIN ကုဒ် ရိုက်ထည့်ပါ"</string>
<string name="keyguard_password_enter_puk_code" msgid="3035856550289724338">"ဆင်းမ်ကဒ် ပင်နံပါတ် ပြန်ဖွင့်သည့် ကုဒ် နှင့် လျို့ဝှက်နံပါတ်သစ် ရိုက်ထည့်ပါ"</string>
<string name="keyguard_password_enter_puk_prompt" msgid="1801941051094974609">"ဆင်းမ်ကဒ် ပင်နံပါတ် ပြန်ဖွင့်သည့် ကုဒ် နံပါတ်"</string>
<string name="keyguard_password_enter_pin_prompt" msgid="3201151840570492538">"ဆင်းမ်ကဒ် လျို့ဝှက်ပင်နံပါတ် အသစ်သွင်းရန်"</string>
<string name="keyguard_password_entry_touch_hint" msgid="7858547464982981384"><font size="17">"စကားဝှက် ရိုက်ရန် ထိပါ"</font></string>
- <string name="keyguard_password_enter_password_code" msgid="1054721668279049780">"သော့ဖွင့်ရန် စကားဝှက်ကို ရိုက်ထည့်ပါ"</string>
- <string name="keyguard_password_enter_pin_password_code" msgid="6391755146112503443">"သော့ဖွင့်ရန် PIN ကို ရိုက်ထည့်ပါ"</string>
+ <string name="keyguard_password_enter_password_code" msgid="1054721668279049780">"သော့ဖွင့်ရန် စကားဝှက်ကို ရိုက်ထည့်ပါ"</string>
+ <string name="keyguard_password_enter_pin_password_code" msgid="6391755146112503443">"သော့ဖွင့်ရန် PIN ကို ရိုက်ထည့်ပါ"</string>
<string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"ပင်နံပါတ်မှားနေပါသည်"</string>
- <string name="keyguard_label_text" msgid="861796461028298424">"သော့ဖွင့်ရန် Menu ထိုနောက်0ကိုနှိပ်ပါ"</string>
+ <string name="keyguard_label_text" msgid="861796461028298424">"သော့ဖွင့်ရန် Menu ထိုနောက်0ကိုနှိပ်ပါ"</string>
<string name="faceunlock_multiple_failures" msgid="754137583022792429">"မျက်မှာမှတ် သော့ဖွင့်ခြင်း ခွင့်ပြုသော အကြိမ်ရေထက် ကျော်လွန်သွားပါပြီ"</string>
<string name="keyguard_charged" msgid="3272223906073492454">"အားသွင်းနေပါသည်"</string>
<string name="keyguard_plugged_in" msgid="9087497435553252863">"အားသွင်းနေ"</string>
<string name="keyguard_low_battery" msgid="8143808018719173859">"အားသွင်းကြိုးဖြင့် ဆက်သွယ်ပါ"</string>
<string name="keyguard_instructions_when_pattern_disabled" msgid="1332288268600329841">"မီနူးကို နှိပ်ခြင်းဖြင့် သော့ဖွင့်ပါ"</string>
- <string name="keyguard_network_locked_message" msgid="9169717779058037168">"ကွန်ယက် သော့ကျနေခြင်း"</string>
+ <string name="keyguard_network_locked_message" msgid="9169717779058037168">"ကွန်ရက် သော့ကျနေခြင်း"</string>
<string name="keyguard_missing_sim_message_short" msgid="494980561304211931">"ဆင်းမ်ကဒ်မရှိပါ"</string>
<string name="keyguard_missing_sim_message" product="tablet" msgid="1445849005909260039">"တက်ဘလက်ထဲတွင်း ဆင်းမ်ကဒ် မရှိပါ"</string>
<string name="keyguard_missing_sim_message" product="default" msgid="3481110395508637643">"ဖုန်းထဲတွင် ဆင်းမ်ကဒ် မရှိပါ"</string>
@@ -85,14 +85,14 @@
<string name="keyboardview_keycode_alt" msgid="4856868820040051939">"Altခလုတ်"</string>
<string name="keyboardview_keycode_cancel" msgid="1203984017245783244">"ပယ်ဖျက်ရန်ခလုတ်"</string>
<string name="keyboardview_keycode_delete" msgid="3337914833206635744">"ဖျက်ရန်ခလုတ်"</string>
- <string name="keyboardview_keycode_done" msgid="1992571118466679775">"ပြီးဆုံးသည့်ခလုတ်"</string>
+ <string name="keyboardview_keycode_done" msgid="1992571118466679775">"ပြီးဆုံးသည့်ခလုတ်"</string>
<string name="keyboardview_keycode_mode_change" msgid="4547387741906537519">"စနစ်ပြောင်းခြင်းခလုတ်"</string>
<string name="keyboardview_keycode_shift" msgid="2270748814315147690">"Shiftခလုတ်"</string>
<string name="keyboardview_keycode_enter" msgid="2985864015076059467">"Enterခလုတ်"</string>
- <string name="description_target_unlock" msgid="2228524900439801453">"ဖွင့်ရန်"</string>
+ <string name="description_target_unlock" msgid="2228524900439801453">"ဖွင့်ရန်"</string>
<string name="description_target_camera" msgid="969071997552486814">"ကင်မရာ"</string>
<string name="description_target_silent" msgid="893551287746522182">"အသံတိတ်ရန်"</string>
- <string name="description_target_soundon" msgid="30052466675500172">"အသံဖွင့်သည်"</string>
+ <string name="description_target_soundon" msgid="30052466675500172">"အသံဖွင့်သည်"</string>
<string name="description_target_search" msgid="3091587249776033139">"ရှာဖွေရန်"</string>
<string name="description_direction_up" msgid="7169032478259485180">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> အတွက် အပေါ်ကို ပွတ်ဆွဲပါ"</string>
<string name="description_direction_down" msgid="5087739728639014595">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> အတွက် အောက်ကို ပွတ်ဆွဲပါ"</string>
diff --git a/packages/Keyguard/res/values-sw/strings.xml b/packages/Keyguard/res/values-sw/strings.xml
index 814dc90..b1b7dcd 100644
--- a/packages/Keyguard/res/values-sw/strings.xml
+++ b/packages/Keyguard/res/values-sw/strings.xml
@@ -39,8 +39,8 @@
<string name="keyguard_missing_sim_message_short" msgid="494980561304211931">"Hakuna SIM kadi"</string>
<string name="keyguard_missing_sim_message" product="tablet" msgid="1445849005909260039">"Hakuna SIM kadi katika kompyuta ndogo."</string>
<string name="keyguard_missing_sim_message" product="default" msgid="3481110395508637643">"Hakuna SIM kadi kwenye simu."</string>
- <string name="keyguard_missing_sim_instructions" msgid="5210891509995942250">"Ingiza SIM kadi."</string>
- <string name="keyguard_missing_sim_instructions_long" msgid="5968985489463870358">"SIM kadi haiko au haisomeki. Ingiza SIM kadi."</string>
+ <string name="keyguard_missing_sim_instructions" msgid="5210891509995942250">"Weka SIM kadi."</string>
+ <string name="keyguard_missing_sim_instructions_long" msgid="5968985489463870358">"SIM kadi haiko au haisomeki. Weka SIM kadi."</string>
<string name="keyguard_permanent_disabled_sim_message_short" msgid="8340813989586622356">"SIM kadi isiyotumika."</string>
<string name="keyguard_permanent_disabled_sim_instructions" msgid="5892940909699723544">"SIM kadi yako imefungwa kabisa.\n Wasiliana na mtoa huduma wako wa pasi waya ili upate SIM kadi nyingine."</string>
<string name="keyguard_sim_locked_message" msgid="6875773413306380902">"SIM kadi imefungwa."</string>
@@ -103,7 +103,7 @@
<string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"Umesahau Ruwaza"</string>
<string name="kg_wrong_pattern" msgid="1850806070801358830">"Mchoro Usio sahihi"</string>
<string name="kg_wrong_password" msgid="2333281762128113157">"Nenosiri Lisilo sahihi"</string>
- <string name="kg_wrong_pin" msgid="1131306510833563801">"PIN isiyo sahihi"</string>
+ <string name="kg_wrong_pin" msgid="1131306510833563801">"Nambari ya PIN si sahihi"</string>
<string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"Jaribu tena baada ya sekunde <xliff:g id="NUMBER">%d</xliff:g>."</string>
<string name="kg_pattern_instructions" msgid="398978611683075868">"Chora ruwaza yako"</string>
<string name="kg_sim_pin_instructions" msgid="2319508550934557331">"Ingiza PIN ya SIM"</string>
diff --git a/packages/Keyguard/res/values-ta-rIN/strings.xml b/packages/Keyguard/res/values-ta-rIN/strings.xml
index e4b81db..0fe8fcc 100644
--- a/packages/Keyguard/res/values-ta-rIN/strings.xml
+++ b/packages/Keyguard/res/values-ta-rIN/strings.xml
@@ -21,14 +21,14 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_name" msgid="719438068451601849">"விசைப்பாதுகாப்பு"</string>
- <string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"PIN குறியீட்டை உள்ளிடவும்"</string>
- <string name="keyguard_password_enter_puk_code" msgid="3035856550289724338">"SIM PUK மற்றும் புதிய PIN குறியீட்டைத் தட்டச்சு செய்யவும்"</string>
- <string name="keyguard_password_enter_puk_prompt" msgid="1801941051094974609">"SIM PUK குறியீடு"</string>
- <string name="keyguard_password_enter_pin_prompt" msgid="3201151840570492538">"புதிய SIM PIN குறியீடு"</string>
+ <string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"பின் குறியீட்டை உள்ளிடவும்"</string>
+ <string name="keyguard_password_enter_puk_code" msgid="3035856550289724338">"சிம் PUK மற்றும் புதிய பின் குறியீட்டைத் தட்டச்சு செய்யவும்"</string>
+ <string name="keyguard_password_enter_puk_prompt" msgid="1801941051094974609">"சிம் PUK குறியீடு"</string>
+ <string name="keyguard_password_enter_pin_prompt" msgid="3201151840570492538">"புதிய சிம் பின் குறியீடு"</string>
<string name="keyguard_password_entry_touch_hint" msgid="7858547464982981384"><font size="17">"கடவுச்சொல்லை உள்ளிட, தொடவும்"</font></string>
<string name="keyguard_password_enter_password_code" msgid="1054721668279049780">"திறக்க, கடவுச்சொல்லை உள்ளிடவும்"</string>
- <string name="keyguard_password_enter_pin_password_code" msgid="6391755146112503443">"திறக்க, PIN ஐ உள்ளிடவும்"</string>
- <string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"தவறான PIN குறியீடு."</string>
+ <string name="keyguard_password_enter_pin_password_code" msgid="6391755146112503443">"திறக்க, பின்னை உள்ளிடவும்"</string>
+ <string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"தவறான பின் குறியீடு."</string>
<string name="keyguard_label_text" msgid="861796461028298424">"தடைநீக்க, மெனுவை அழுத்தி பின்பு 0 ஐ அழுத்தவும்."</string>
<string name="faceunlock_multiple_failures" msgid="754137583022792429">"முகம் திறப்பதற்கான அதிகபட்ச முயற்சிகள் கடந்தன"</string>
<string name="keyguard_charged" msgid="3272223906073492454">"சார்ஜ் செய்யப்பட்டது"</string>
@@ -36,16 +36,16 @@
<string name="keyguard_low_battery" msgid="8143808018719173859">"உங்கள் சார்ஜரை இணைக்கவும்."</string>
<string name="keyguard_instructions_when_pattern_disabled" msgid="1332288268600329841">"திறக்க, மெனுவை அழுத்தவும்."</string>
<string name="keyguard_network_locked_message" msgid="9169717779058037168">"பிணையம் பூட்டப்பட்டது"</string>
- <string name="keyguard_missing_sim_message_short" msgid="494980561304211931">"SIM கார்டு இல்லை"</string>
- <string name="keyguard_missing_sim_message" product="tablet" msgid="1445849005909260039">"டேப்லெட்டில் SIM கார்டு இல்லை."</string>
- <string name="keyguard_missing_sim_message" product="default" msgid="3481110395508637643">"தொலைபேசியில் SIM கார்டு இல்லை."</string>
- <string name="keyguard_missing_sim_instructions" msgid="5210891509995942250">"SIM கார்டைச் செருகவும்."</string>
- <string name="keyguard_missing_sim_instructions_long" msgid="5968985489463870358">"SIM கார்டு இல்லை அல்லது படிக்கக்கூடியதாக இல்லை. SIM கார்டைச் செருகவும்."</string>
- <string name="keyguard_permanent_disabled_sim_message_short" msgid="8340813989586622356">"SIM கார்டைப் பயன்படுத்த முடியாது."</string>
- <string name="keyguard_permanent_disabled_sim_instructions" msgid="5892940909699723544">"உங்கள் SIM கார்டு நிரந்தரமாக முடக்கப்பட்டது.\n மற்றொரு SIM கார்டிற்காக உங்கள் வயர்லெஸ் சேவை வழங்குநரைத் தொடர்புகொள்ளவும்."</string>
- <string name="keyguard_sim_locked_message" msgid="6875773413306380902">"SIM கார்டு பூட்டப்பட்டுள்ளது."</string>
- <string name="keyguard_sim_puk_locked_message" msgid="3747232467471801633">"SIM கார்டு PUK ஆல் பூட்டப்பட்டது."</string>
- <string name="keyguard_sim_unlock_progress_dialog_message" msgid="7975221805033614426">"SIM கார்டின் தடையைநீக்குகிறது..."</string>
+ <string name="keyguard_missing_sim_message_short" msgid="494980561304211931">"சிம் கார்டு இல்லை"</string>
+ <string name="keyguard_missing_sim_message" product="tablet" msgid="1445849005909260039">"டேப்லெட்டில் சிம் கார்டு இல்லை."</string>
+ <string name="keyguard_missing_sim_message" product="default" msgid="3481110395508637643">"தொலைபேசியில் சிம் கார்டு இல்லை."</string>
+ <string name="keyguard_missing_sim_instructions" msgid="5210891509995942250">"சிம் கார்டைச் செருகவும்."</string>
+ <string name="keyguard_missing_sim_instructions_long" msgid="5968985489463870358">"சிம் கார்டு இல்லை அல்லது படிக்கக்கூடியதாக இல்லை. சிம் கார்டைச் செருகவும்."</string>
+ <string name="keyguard_permanent_disabled_sim_message_short" msgid="8340813989586622356">"சிம் கார்டைப் பயன்படுத்த முடியாது."</string>
+ <string name="keyguard_permanent_disabled_sim_instructions" msgid="5892940909699723544">"உங்கள் சிம் கார்டு நிரந்தரமாக முடக்கப்பட்டது.\n மற்றொரு சிம் கார்டிற்காக உங்கள் வயர்லெஸ் சேவை வழங்குநரைத் தொடர்புகொள்ளவும்."</string>
+ <string name="keyguard_sim_locked_message" msgid="6875773413306380902">"சிம் கார்டு பூட்டப்பட்டுள்ளது."</string>
+ <string name="keyguard_sim_puk_locked_message" msgid="3747232467471801633">"சிம் கார்டு PUK ஆல் பூட்டப்பட்டது."</string>
+ <string name="keyguard_sim_unlock_progress_dialog_message" msgid="7975221805033614426">"சிம் கார்டின் தடையைநீக்குகிறது..."</string>
<string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. விட்ஜெட் %2$d / %3$d."</string>
<string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"விட்ஜெட்டைச் சேர்க்கவும்."</string>
<string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"காலியானது"</string>
@@ -103,20 +103,20 @@
<string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"வடிவத்தை மறந்துவிட்டீர்களா"</string>
<string name="kg_wrong_pattern" msgid="1850806070801358830">"தவறான வடிவம்"</string>
<string name="kg_wrong_password" msgid="2333281762128113157">"தவறான கடவுச்சொல்"</string>
- <string name="kg_wrong_pin" msgid="1131306510833563801">"தவறான PIN"</string>
+ <string name="kg_wrong_pin" msgid="1131306510833563801">"தவறான பின்"</string>
<string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"<xliff:g id="NUMBER">%d</xliff:g> வினாடிகள் கழித்து முயற்சிக்கவும்."</string>
- <string name="kg_pattern_instructions" msgid="398978611683075868">"உங்கள் வடிவத்தை வரையவும்"</string>
- <string name="kg_sim_pin_instructions" msgid="2319508550934557331">"SIM PIN ஐ உள்ளிடவும்"</string>
- <string name="kg_pin_instructions" msgid="2377242233495111557">"PIN ஐ உள்ளிடுக"</string>
+ <string name="kg_pattern_instructions" msgid="398978611683075868">"வடிவத்தை வரையவும்"</string>
+ <string name="kg_sim_pin_instructions" msgid="2319508550934557331">"சிம் பின்னை உள்ளிடவும்"</string>
+ <string name="kg_pin_instructions" msgid="2377242233495111557">"பின்னை உள்ளிடுக"</string>
<string name="kg_password_instructions" msgid="5753646556186936819">"கடவுச்சொல்லை உள்ளிடவும்"</string>
- <string name="kg_puk_enter_puk_hint" msgid="453227143861735537">"SIM தற்போது முடக்கப்பட்டுள்ளது. தொடர்வதற்கு PUK குறியீட்டை உள்ளிடவும். விவரங்களுக்கு மொபைல் நிறுவனங்களைத் தொடர்புகொள்ளவும்."</string>
- <string name="kg_puk_enter_pin_hint" msgid="7871604527429602024">"விரும்பிய PIN குறியீட்டை உள்ளிடவும்"</string>
- <string name="kg_enter_confirm_pin_hint" msgid="325676184762529976">"விரும்பிய PIN குறியீட்டை உறுதிப்படுத்தவும்"</string>
- <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"SIM கார்டின் தடையைநீக்குகிறது..."</string>
- <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"4 இலிருந்து 8 எண்கள் வரையுள்ள PIN ஐ உள்ளிடவும்."</string>
+ <string name="kg_puk_enter_puk_hint" msgid="453227143861735537">"சிம் தற்போது முடக்கப்பட்டுள்ளது. தொடர்வதற்கு PUK குறியீட்டை உள்ளிடவும். விவரங்களுக்கு மொபைல் நிறுவனங்களைத் தொடர்புகொள்ளவும்."</string>
+ <string name="kg_puk_enter_pin_hint" msgid="7871604527429602024">"விரும்பிய பின் குறியீட்டை உள்ளிடவும்"</string>
+ <string name="kg_enter_confirm_pin_hint" msgid="325676184762529976">"விரும்பிய பின் குறியீட்டை உறுதிப்படுத்தவும்"</string>
+ <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"சிம் கார்டின் தடையைநீக்குகிறது..."</string>
+ <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"4 இலிருந்து 8 எண்கள் வரையுள்ள பின்னை உள்ளிடவும்."</string>
<string name="kg_invalid_sim_puk_hint" msgid="7553388325654369575">"PUK குறியீட்டில் 8 எண்கள் அல்லது அதற்கு மேல் இருக்க வேண்டும்."</string>
- <string name="kg_invalid_puk" msgid="3638289409676051243">"சரியான PUK குறியீட்டை மீண்டும் உள்ளிடவும். தொடர் முயற்சிகள் SIM ஐ நிரந்தரமாக முடக்கிவிடும்."</string>
- <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"PIN குறியீடுகள் பொருந்தவில்லை"</string>
+ <string name="kg_invalid_puk" msgid="3638289409676051243">"சரியான PUK குறியீட்டை மீண்டும் உள்ளிடவும். தொடர் முயற்சிகள் சிம் ஐ நிரந்தரமாக முடக்கிவிடும்."</string>
+ <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"பின் குறியீடுகள் பொருந்தவில்லை"</string>
<string name="kg_login_too_many_attempts" msgid="6486842094005698475">"அதிகமான வடிவ முயற்சிகள்"</string>
<string name="kg_login_instructions" msgid="1100551261265506448">"திறக்க, உங்கள் Google கணக்கு மூலம் உள்நுழையவும்."</string>
<string name="kg_login_username_hint" msgid="5718534272070920364">"பயனர்பெயர் (மின்னஞ்சல்)"</string>
@@ -125,7 +125,7 @@
<string name="kg_login_invalid_input" msgid="5754664119319872197">"தவறான பயனர்பெயர் அல்லது கடவுச்சொல்."</string>
<string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"உங்கள் பயனர்பெயர் அல்லது கடவுச்சொல்லை மறந்துவிட்டீர்களா?\n"<b>"google.com/accounts/recovery"</b>" ஐப் பார்வையிடவும்."</string>
<string name="kg_login_checking_password" msgid="1052685197710252395">"கணக்கைச் சரிபார்க்கிறது…"</string>
- <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"உங்கள் PIN ஐ <xliff:g id="NUMBER_0">%d</xliff:g> முறை தவறாக உள்ளிட்டீர்கள். \n\n<xliff:g id="NUMBER_1">%d</xliff:g> வினாடிகள் கழித்து முயற்சிக்கவும்."</string>
+ <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"உங்கள் பின்னை <xliff:g id="NUMBER_0">%d</xliff:g> முறை தவறாக உள்ளிட்டீர்கள். \n\n<xliff:g id="NUMBER_1">%d</xliff:g> வினாடிகள் கழித்து முயற்சிக்கவும்."</string>
<string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"உங்கள் கடவுச்சொல்லை <xliff:g id="NUMBER_0">%d</xliff:g> முறை தவறாக உள்ளிட்டீர்கள். \n\n<xliff:g id="NUMBER_1">%d</xliff:g> வினாடிகள் கழித்து முயற்சிக்கவும்."</string>
<string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"திறப்பதற்கான வடிவத்தை <xliff:g id="NUMBER_0">%d</xliff:g> முறை தவறாக வரைந்துள்ளீர்கள். \n\n<xliff:g id="NUMBER_1">%d</xliff:g> வினாடிகளில் மீண்டும் முயற்சிக்கவும்."</string>
<string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"டேப்லெட்டைத் திறக்க <xliff:g id="NUMBER_0">%d</xliff:g> முறை தவறாக முயற்சித்துள்ளீர்கள். இன்னும் <xliff:g id="NUMBER_1">%d</xliff:g> தோல்வி முயற்சிகளுக்குப் பிறகு, டேப்லெட்டானது ஆரம்பநிலைக்கு மீட்டமைக்கப்பட்டு, எல்லா பயனர் தரவையும் இழப்பீர்கள்."</string>
@@ -136,18 +136,18 @@
<string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"திறப்பதற்கான வடிவத்தை <xliff:g id="NUMBER_0">%d</xliff:g> முறை தவறாக வரைந்துள்ளீர்கள். மேலும் <xliff:g id="NUMBER_1">%d</xliff:g> தோல்வி முயற்சிகளுக்குப் பிறகு, மின்னஞ்சல் கணக்கைப் பயன்படுத்தி உங்கள் மொபைலைத் திறக்கக் கேட்கப்படுவீர்கள்.\n\n <xliff:g id="NUMBER_2">%d</xliff:g> வினாடிகள் கழித்து முயற்சிக்கவும்."</string>
<string name="kg_text_message_separator" product="default" msgid="4160700433287233771">" — "</string>
<string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"அகற்று"</string>
- <string name="kg_password_wrong_pin_code_pukked" msgid="30531039455764924">"SIM PIN குறியீடு தவறானது, உங்கள் சாதனத்தின் தடையை நீக்க, உங்கள் மொபைல் நிறுவனத்தைத் தொடர்புகொள்ள வேண்டும்."</string>
+ <string name="kg_password_wrong_pin_code_pukked" msgid="30531039455764924">"சிம் பின் குறியீடு தவறானது, உங்கள் சாதனத்தின் தடையை நீக்க, உங்கள் மொபைல் நிறுவனத்தைத் தொடர்புகொள்ள வேண்டும்."</string>
<plurals name="kg_password_wrong_pin_code">
- <item quantity="one" msgid="8134313997799638254">"SIM PIN குறியீடு தவறானது, உங்கள் சாதனத்தைத் திறக்க, உங்கள் மொபைல் நிறுவனத்தைத் தொடர்புகொள்ளும் முன், மேலும் <xliff:g id="NUMBER">%d</xliff:g> முறை முயர்ச்சிக்கலாம்."</item>
- <item quantity="other" msgid="2215723361575359486">"SIM PIN குறியீடு தவறானது, மேலும் <xliff:g id="NUMBER">%d</xliff:g> முறை முயற்சிக்கலாம்."</item>
+ <item quantity="one" msgid="8134313997799638254">"சிம் பின் குறியீடு தவறானது, உங்கள் சாதனத்தைத் திறக்க, உங்கள் மொபைல் நிறுவனத்தைத் தொடர்புகொள்ளும் முன், மேலும் <xliff:g id="NUMBER">%d</xliff:g> முறை முயர்ச்சிக்கலாம்."</item>
+ <item quantity="other" msgid="2215723361575359486">"சிம் பின் குறியீடு தவறானது, மேலும் <xliff:g id="NUMBER">%d</xliff:g> முறை முயற்சிக்கலாம்."</item>
</plurals>
- <string name="kg_password_wrong_puk_code_dead" msgid="7077536808291316208">"SIM பயன்பாட்டிற்கு உகந்தது அல்ல. உங்கள் மொபைல் நிறுவனத்தைத் தொடர்புகொள்ளவும்."</string>
+ <string name="kg_password_wrong_puk_code_dead" msgid="7077536808291316208">"சிம் பயன்பாட்டிற்கு உகந்தது அல்ல. உங்கள் மொபைல் நிறுவனத்தைத் தொடர்புகொள்ளவும்."</string>
<plurals name="kg_password_wrong_puk_code">
- <item quantity="one" msgid="3256893607561060649">"SIM PUK குறியீடு தவறானது, சிம் நிரந்தரமாகப் பயன்படுத்த முடியாமல் போவதற்கு முன், நீங்கள் <xliff:g id="NUMBER">%d</xliff:g> முறை முயர்ச்சிக்கலாம்."</item>
- <item quantity="other" msgid="5477305226026342036">"SIM PUK குறியீடு தவறானது, SIM நிரந்தரமாகப் பயன்படுத்த முடியாமல் போவதற்கு முன், நீங்கள் <xliff:g id="NUMBER">%d</xliff:g> முறை முயற்சிக்கலாம்."</item>
+ <item quantity="one" msgid="3256893607561060649">"சிம் PUK குறியீடு தவறானது, சிம் நிரந்தரமாகப் பயன்படுத்த முடியாமல் போவதற்கு முன், நீங்கள் <xliff:g id="NUMBER">%d</xliff:g> முறை முயர்ச்சிக்கலாம்."</item>
+ <item quantity="other" msgid="5477305226026342036">"சிம் PUK குறியீடு தவறானது, சிம் நிரந்தரமாகப் பயன்படுத்த முடியாமல் போவதற்கு முன், நீங்கள் <xliff:g id="NUMBER">%d</xliff:g> முறை முயற்சிக்கலாம்."</item>
</plurals>
- <string name="kg_password_pin_failed" msgid="6268288093558031564">"SIM PIN செயல்பாடு தோல்வி!"</string>
- <string name="kg_password_puk_failed" msgid="2838824369502455984">"SIM PUK செயல்பாடு தோல்வி!"</string>
+ <string name="kg_password_pin_failed" msgid="6268288093558031564">"சிம் பின் செயல்பாடு தோல்வி!"</string>
+ <string name="kg_password_puk_failed" msgid="2838824369502455984">"சிம் PUK செயல்பாடு தோல்வி!"</string>
<string name="kg_pin_accepted" msgid="1448241673570020097">"குறியீடு ஏற்கப்பட்டது!"</string>
<string name="keyguard_transport_prev_description" msgid="8229108430245669854">"முந்தைய டிராக்கிற்கான பொத்தான்"</string>
<string name="keyguard_transport_next_description" msgid="4299258300283778305">"அடுத்த டிராக்கிற்கான பொத்தான்"</string>
diff --git a/packages/Keyguard/res/values-te-rIN/strings.xml b/packages/Keyguard/res/values-te-rIN/strings.xml
index 635301e..946631a 100644
--- a/packages/Keyguard/res/values-te-rIN/strings.xml
+++ b/packages/Keyguard/res/values-te-rIN/strings.xml
@@ -21,14 +21,14 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_name" msgid="719438068451601849">"కీగార్డ్"</string>
- <string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"PIN కోడ్ను టైప్ చేయండి"</string>
- <string name="keyguard_password_enter_puk_code" msgid="3035856550289724338">"SIM PUK మరియు కొత్త PIN కోడ్ను టైప్ చేయండి"</string>
- <string name="keyguard_password_enter_puk_prompt" msgid="1801941051094974609">"SIM PUK కోడ్"</string>
- <string name="keyguard_password_enter_pin_prompt" msgid="3201151840570492538">"కొత్త SIM PIN కోడ్"</string>
+ <string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"పిన్ కోడ్ను టైప్ చేయండి"</string>
+ <string name="keyguard_password_enter_puk_code" msgid="3035856550289724338">"సిమ్ PUK మరియు కొత్త పిన్ కోడ్ను టైప్ చేయండి"</string>
+ <string name="keyguard_password_enter_puk_prompt" msgid="1801941051094974609">"సిమ్ PUK కోడ్"</string>
+ <string name="keyguard_password_enter_pin_prompt" msgid="3201151840570492538">"కొత్త సిమ్ పిన్ కోడ్"</string>
<string name="keyguard_password_entry_touch_hint" msgid="7858547464982981384"><font size="17">"పాస్వర్డ్ను టైప్ చేయడానికి తాకండి"</font></string>
<string name="keyguard_password_enter_password_code" msgid="1054721668279049780">"అన్లాక్ చేయడానికి పాస్వర్డ్ను టైప్ చేయండి"</string>
- <string name="keyguard_password_enter_pin_password_code" msgid="6391755146112503443">"అన్లాక్ చేయడానికి PINను టైప్ చేయండి"</string>
- <string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"చెల్లని PIN కోడ్."</string>
+ <string name="keyguard_password_enter_pin_password_code" msgid="6391755146112503443">"అన్లాక్ చేయడానికి పిన్ను టైప్ చేయండి"</string>
+ <string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"చెల్లని పిన్ కోడ్."</string>
<string name="keyguard_label_text" msgid="861796461028298424">"అన్లాక్ చేయడానికి, మెను ఆపై 0ని నొక్కండి."</string>
<string name="faceunlock_multiple_failures" msgid="754137583022792429">"ముఖంతో అన్లాక్ ప్రయత్నాల గరిష్ట పరిమితి మించిపోయారు"</string>
<string name="keyguard_charged" msgid="3272223906073492454">"ఛార్జ్ అయింది"</string>
@@ -36,16 +36,16 @@
<string name="keyguard_low_battery" msgid="8143808018719173859">"మీ ఛార్జర్ను కనెక్ట్ చేయండి."</string>
<string name="keyguard_instructions_when_pattern_disabled" msgid="1332288268600329841">"అన్లాక్ చేయడానికి మెను నొక్కండి."</string>
<string name="keyguard_network_locked_message" msgid="9169717779058037168">"నెట్వర్క్ లాక్ చేయబడింది"</string>
- <string name="keyguard_missing_sim_message_short" msgid="494980561304211931">"SIM కార్డు లేదు"</string>
- <string name="keyguard_missing_sim_message" product="tablet" msgid="1445849005909260039">"టాబ్లెట్లో SIM కార్డు లేదు."</string>
- <string name="keyguard_missing_sim_message" product="default" msgid="3481110395508637643">"ఫోన్లో SIM కార్డు లేదు."</string>
- <string name="keyguard_missing_sim_instructions" msgid="5210891509995942250">"SIM కార్డును చొప్పించండి."</string>
- <string name="keyguard_missing_sim_instructions_long" msgid="5968985489463870358">"SIM కార్డు లేదు లేదా చదవగలిగేలా లేదు. SIM కార్డును చొప్పించండి."</string>
- <string name="keyguard_permanent_disabled_sim_message_short" msgid="8340813989586622356">"నిరుపయోగ SIM కార్డు."</string>
- <string name="keyguard_permanent_disabled_sim_instructions" msgid="5892940909699723544">"మీ SIM కార్డు శాశ్వతంగా నిలిపివేయబడింది.\n మరో SIM కార్డు కోసం మీ వైర్లెస్ సేవా ప్రదాతను సంప్రదించండి."</string>
- <string name="keyguard_sim_locked_message" msgid="6875773413306380902">"SIM కార్డు లాక్ చేయబడింది."</string>
- <string name="keyguard_sim_puk_locked_message" msgid="3747232467471801633">"SIM కార్డు PUK లాక్ చేయబడింది."</string>
- <string name="keyguard_sim_unlock_progress_dialog_message" msgid="7975221805033614426">"SIM కార్డును అన్లాక్ చేస్తోంది…"</string>
+ <string name="keyguard_missing_sim_message_short" msgid="494980561304211931">"సిమ్ కార్డు లేదు"</string>
+ <string name="keyguard_missing_sim_message" product="tablet" msgid="1445849005909260039">"టాబ్లెట్లో సిమ్ కార్డు లేదు."</string>
+ <string name="keyguard_missing_sim_message" product="default" msgid="3481110395508637643">"ఫోన్లో సిమ్ కార్డు లేదు."</string>
+ <string name="keyguard_missing_sim_instructions" msgid="5210891509995942250">"సిమ్ కార్డును చొప్పించండి."</string>
+ <string name="keyguard_missing_sim_instructions_long" msgid="5968985489463870358">"సిమ్ కార్డు లేదు లేదా చదవగలిగేలా లేదు. సిమ్ కార్డును చొప్పించండి."</string>
+ <string name="keyguard_permanent_disabled_sim_message_short" msgid="8340813989586622356">"నిరుపయోగ సిమ్ కార్డు."</string>
+ <string name="keyguard_permanent_disabled_sim_instructions" msgid="5892940909699723544">"మీ సిమ్ కార్డు శాశ్వతంగా నిలిపివేయబడింది.\n మరో సిమ్ కార్డు కోసం మీ వైర్లెస్ సేవా ప్రదాతను సంప్రదించండి."</string>
+ <string name="keyguard_sim_locked_message" msgid="6875773413306380902">"సిమ్ కార్డు లాక్ చేయబడింది."</string>
+ <string name="keyguard_sim_puk_locked_message" msgid="3747232467471801633">"సిమ్ కార్డు PUK లాక్ చేయబడింది."</string>
+ <string name="keyguard_sim_unlock_progress_dialog_message" msgid="7975221805033614426">"సిమ్ కార్డును అన్లాక్ చేస్తోంది…"</string>
<string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. %3$dలో విడ్జెట్ %2$d."</string>
<string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"విడ్జెట్ను జోడించండి."</string>
<string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"ఖాళీ"</string>
@@ -103,20 +103,20 @@
<string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"నమూనాను మర్చిపోయాను"</string>
<string name="kg_wrong_pattern" msgid="1850806070801358830">"నమూనా తప్పు"</string>
<string name="kg_wrong_password" msgid="2333281762128113157">"పాస్వర్డ్ తప్పు"</string>
- <string name="kg_wrong_pin" msgid="1131306510833563801">"PIN తప్పు"</string>
+ <string name="kg_wrong_pin" msgid="1131306510833563801">"పిన్ తప్పు"</string>
<string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"<xliff:g id="NUMBER">%d</xliff:g> సెకన్లలో మళ్లీ ప్రయత్నించండి."</string>
<string name="kg_pattern_instructions" msgid="398978611683075868">"మీ నమూనాను గీయండి"</string>
- <string name="kg_sim_pin_instructions" msgid="2319508550934557331">"SIM PINను నమోదు చేయండి"</string>
- <string name="kg_pin_instructions" msgid="2377242233495111557">"PINను నమోదు చేయండి"</string>
+ <string name="kg_sim_pin_instructions" msgid="2319508550934557331">"సిమ్ పిన్ను నమోదు చేయండి"</string>
+ <string name="kg_pin_instructions" msgid="2377242233495111557">"పిన్ను నమోదు చేయండి"</string>
<string name="kg_password_instructions" msgid="5753646556186936819">"పాస్వర్డ్ని నమోదు చేయండి"</string>
- <string name="kg_puk_enter_puk_hint" msgid="453227143861735537">"SIM ఇప్పుడు నిలిపివేయబడింది. కొనసాగడానికి PUK కోడ్ను నమోదు చేయండి. వివరాల కోసం క్యారియర్ను సంప్రదించండి."</string>
- <string name="kg_puk_enter_pin_hint" msgid="7871604527429602024">"కోరుకునే PIN కోడ్ను నమోదు చేయండి"</string>
- <string name="kg_enter_confirm_pin_hint" msgid="325676184762529976">"కావల్సిన PIN కోడ్ను నిర్ధారించండి"</string>
- <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"SIM కార్డును అన్లాక్ చేస్తోంది…"</string>
- <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"4 నుండి 8 సంఖ్యలు ఉండే PINను టైప్ చేయండి."</string>
+ <string name="kg_puk_enter_puk_hint" msgid="453227143861735537">"సిమ్ ఇప్పుడు నిలిపివేయబడింది. కొనసాగడానికి PUK కోడ్ను నమోదు చేయండి. వివరాల కోసం క్యారియర్ను సంప్రదించండి."</string>
+ <string name="kg_puk_enter_pin_hint" msgid="7871604527429602024">"కోరుకునే పిన్ కోడ్ను నమోదు చేయండి"</string>
+ <string name="kg_enter_confirm_pin_hint" msgid="325676184762529976">"కావల్సిన పిన్ కోడ్ను నిర్ధారించండి"</string>
+ <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"సిమ్ కార్డును అన్లాక్ చేస్తోంది…"</string>
+ <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"4 నుండి 8 సంఖ్యలు ఉండే పిన్ను టైప్ చేయండి."</string>
<string name="kg_invalid_sim_puk_hint" msgid="7553388325654369575">"PUK కోడ్ 8 లేదా అంతకంటే ఎక్కువ సంఖ్యలు ఉండాలి."</string>
- <string name="kg_invalid_puk" msgid="3638289409676051243">"సరైన PUK కోడ్ను మళ్లీ నమోదు చేయండి. పునరావృత ప్రయత్నాల వలన SIM శాశ్వతంగా నిలిపివేయబడుతుంది."</string>
- <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"PIN కోడ్లు సరిపోలలేదు"</string>
+ <string name="kg_invalid_puk" msgid="3638289409676051243">"సరైన PUK కోడ్ను మళ్లీ నమోదు చేయండి. పునరావృత ప్రయత్నాల వలన సిమ్ శాశ్వతంగా నిలిపివేయబడుతుంది."</string>
+ <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"పిన్ కోడ్లు సరిపోలలేదు"</string>
<string name="kg_login_too_many_attempts" msgid="6486842094005698475">"చాలా ఎక్కువ నమూనా ప్రయత్నాలు చేసారు"</string>
<string name="kg_login_instructions" msgid="1100551261265506448">"అన్లాక్ చేయడానికి, మీ Google ఖాతాతో సైన్ ఇన్ చేయండి."</string>
<string name="kg_login_username_hint" msgid="5718534272070920364">"వినియోగదారు పేరు (ఇమెయిల్)"</string>
@@ -125,7 +125,7 @@
<string name="kg_login_invalid_input" msgid="5754664119319872197">"చెల్లని వినియోగదారు పేరు లేదా పాస్వర్డ్."</string>
<string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"మీ వినియోగదారు పేరు లేదా పాస్వర్డ్ను మర్చిపోయారా?\n"<b>"google.com/accounts/recovery"</b>"ని సందర్శించండి."</string>
<string name="kg_login_checking_password" msgid="1052685197710252395">"ఖాతాను తనిఖీ చేస్తోంది…"</string>
- <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"మీరు మీ PINను <xliff:g id="NUMBER_0">%d</xliff:g> సార్లు తప్పుగా టైప్ చేసారు. \n\n<xliff:g id="NUMBER_1">%d</xliff:g> సెకన్లలో మళ్లీ ప్రయత్నించండి."</string>
+ <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"మీరు మీ పిన్ను <xliff:g id="NUMBER_0">%d</xliff:g> సార్లు తప్పుగా టైప్ చేసారు. \n\n<xliff:g id="NUMBER_1">%d</xliff:g> సెకన్లలో మళ్లీ ప్రయత్నించండి."</string>
<string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"మీరు మీ పాస్వర్డ్ను <xliff:g id="NUMBER_0">%d</xliff:g> సార్లు తప్పుగా టైప్ చేసారు. \n\n<xliff:g id="NUMBER_1">%d</xliff:g> సెకన్లలో మళ్లీ ప్రయత్నించండి."</string>
<string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"మీరు మీ అన్లాక్ నమూనాను <xliff:g id="NUMBER_0">%d</xliff:g> సార్లు తప్పుగా గీసారు. \n\n<xliff:g id="NUMBER_1">%d</xliff:g> సెకన్లలో మళ్లీ ప్రయత్నించండి."</string>
<string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"మీరు టాబ్లెట్ను అన్లాక్ చేయడానికి <xliff:g id="NUMBER_0">%d</xliff:g> చెల్లని ప్రయత్నాలు చేసారు. మరో <xliff:g id="NUMBER_1">%d</xliff:g> విఫల ప్రయత్నాల తర్వాత, టాబ్లెట్ ఫ్యాక్టరీ డిఫాల్ట్కు రీసెట్ చేయబడుతుంది మరియు మొత్తం వినియోగదారు డేటాను కోల్పోవడం సంభవిస్తుంది."</string>
@@ -136,18 +136,18 @@
<string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"మీరు మీ అన్లాక్ నమూనాను <xliff:g id="NUMBER_0">%d</xliff:g> సార్లు తప్పుగా గీసారు. మరో <xliff:g id="NUMBER_1">%d</xliff:g> విఫల ప్రయత్నాల తర్వాత, ఇమెయిల్ ఖాతాను ఉపయోగించి మీ ఫోన్ను అన్లాక్ చేయాల్సిందిగా మిమ్మల్ని అడుగుతారు.\n\n <xliff:g id="NUMBER_2">%d</xliff:g> సెకన్లలో మళ్లీ ప్రయత్నించండి."</string>
<string name="kg_text_message_separator" product="default" msgid="4160700433287233771">" — "</string>
<string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"తీసివేయి"</string>
- <string name="kg_password_wrong_pin_code_pukked" msgid="30531039455764924">"SIM PIN కోడ్ చెల్లదు, మీరు ఇప్పుడు మీ పరికరాన్ని అన్లాక్ చేయడానికి తప్పనిసరిగా మీ క్యారియర్ను సంప్రదించండి."</string>
+ <string name="kg_password_wrong_pin_code_pukked" msgid="30531039455764924">"సిమ్ పిన్ కోడ్ చెల్లదు, మీరు ఇప్పుడు మీ పరికరాన్ని అన్లాక్ చేయడానికి తప్పనిసరిగా మీ క్యారియర్ను సంప్రదించండి."</string>
<plurals name="kg_password_wrong_pin_code">
- <item quantity="one" msgid="8134313997799638254">"SIM PIN కోడ్ చెల్లదు, మీరు మీ పరికరాన్ని అన్లాక్ చేయడానికి తప్పనిసరిగా మీ క్యారియర్ను సంప్రదించాల్సిన పరిస్థితి ఏర్పడకుండా ఉండటానికి మీకు <xliff:g id="NUMBER">%d</xliff:g> ప్రయత్నం మిగిలి ఉంది."</item>
- <item quantity="other" msgid="2215723361575359486">"SIM PIN కోడ్ చెల్లదు, మీకు <xliff:g id="NUMBER">%d</xliff:g> ప్రయత్నాలు మిగిలి ఉన్నాయి."</item>
+ <item quantity="one" msgid="8134313997799638254">"సిమ్ పిన్ కోడ్ చెల్లదు, మీరు మీ పరికరాన్ని అన్లాక్ చేయడానికి తప్పనిసరిగా మీ క్యారియర్ను సంప్రదించాల్సిన పరిస్థితి ఏర్పడకుండా ఉండటానికి మీకు <xliff:g id="NUMBER">%d</xliff:g> ప్రయత్నం మిగిలి ఉంది."</item>
+ <item quantity="other" msgid="2215723361575359486">"సిమ్ పిన్ కోడ్ చెల్లదు, మీకు <xliff:g id="NUMBER">%d</xliff:g> ప్రయత్నాలు మిగిలి ఉన్నాయి."</item>
</plurals>
- <string name="kg_password_wrong_puk_code_dead" msgid="7077536808291316208">"SIM నిరుపయోగమైనది. మీ క్యారియర్ను సంప్రదించండి."</string>
+ <string name="kg_password_wrong_puk_code_dead" msgid="7077536808291316208">"సిమ్ నిరుపయోగమైనది. మీ క్యారియర్ను సంప్రదించండి."</string>
<plurals name="kg_password_wrong_puk_code">
- <item quantity="one" msgid="3256893607561060649">"SIM PUK కోడ్ చెల్లదు, SIM శాశ్వతంగా నిరుపయోగం కాకుండా ఉండటానికి మీకు <xliff:g id="NUMBER">%d</xliff:g> ప్రయత్నం మిగిలి ఉంది."</item>
- <item quantity="other" msgid="5477305226026342036">"SIM PUK కోడ్ చెల్లదు, SIM శాశ్వతంగా నిరుపయోగం కాకుండా ఉండటానికి మీకు <xliff:g id="NUMBER">%d</xliff:g> ప్రయత్నాలు మిగిలి ఉన్నాయి."</item>
+ <item quantity="one" msgid="3256893607561060649">"సిమ్ PUK కోడ్ చెల్లదు, సిమ్ శాశ్వతంగా నిరుపయోగం కాకుండా ఉండటానికి మీకు <xliff:g id="NUMBER">%d</xliff:g> ప్రయత్నం మిగిలి ఉంది."</item>
+ <item quantity="other" msgid="5477305226026342036">"సిమ్ PUK కోడ్ చెల్లదు, సిమ్ శాశ్వతంగా నిరుపయోగం కాకుండా ఉండటానికి మీకు <xliff:g id="NUMBER">%d</xliff:g> ప్రయత్నాలు మిగిలి ఉన్నాయి."</item>
</plurals>
- <string name="kg_password_pin_failed" msgid="6268288093558031564">"SIM PIN చర్య విఫలమైంది!"</string>
- <string name="kg_password_puk_failed" msgid="2838824369502455984">"SIM PUK చర్య విఫలమైంది!"</string>
+ <string name="kg_password_pin_failed" msgid="6268288093558031564">"సిమ్ పిన్ చర్య విఫలమైంది!"</string>
+ <string name="kg_password_puk_failed" msgid="2838824369502455984">"సిమ్ PUK చర్య విఫలమైంది!"</string>
<string name="kg_pin_accepted" msgid="1448241673570020097">"కోడ్ ఆమోదించబడింది!"</string>
<string name="keyguard_transport_prev_description" msgid="8229108430245669854">"మునుపటి ట్రాక్ బటన్"</string>
<string name="keyguard_transport_next_description" msgid="4299258300283778305">"తదుపరి ట్రాక్ బటన్"</string>
diff --git a/packages/Keyguard/res/values-zh-rCN/strings.xml b/packages/Keyguard/res/values-zh-rCN/strings.xml
index 8e8c4c8..295df9c 100644
--- a/packages/Keyguard/res/values-zh-rCN/strings.xml
+++ b/packages/Keyguard/res/values-zh-rCN/strings.xml
@@ -21,14 +21,14 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_name" msgid="719438068451601849">"Keyguard"</string>
- <string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"输入 PIN 码"</string>
- <string name="keyguard_password_enter_puk_code" msgid="3035856550289724338">"请输入SIM卡PUK码和新的 PIN 码"</string>
+ <string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"输入PIN码"</string>
+ <string name="keyguard_password_enter_puk_code" msgid="3035856550289724338">"请输入SIM卡PUK码和新的PIN码"</string>
<string name="keyguard_password_enter_puk_prompt" msgid="1801941051094974609">"SIM卡PUK码"</string>
<string name="keyguard_password_enter_pin_prompt" msgid="3201151840570492538">"新SIM卡PIN码"</string>
<string name="keyguard_password_entry_touch_hint" msgid="7858547464982981384"><font size="17">"触摸可输入密码"</font></string>
<string name="keyguard_password_enter_password_code" msgid="1054721668279049780">"输入密码以解锁"</string>
- <string name="keyguard_password_enter_pin_password_code" msgid="6391755146112503443">"输入 PIN 进行解锁"</string>
- <string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"PIN 码有误。"</string>
+ <string name="keyguard_password_enter_pin_password_code" msgid="6391755146112503443">"输入PIN码进行解锁"</string>
+ <string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"PIN码有误。"</string>
<string name="keyguard_label_text" msgid="861796461028298424">"要解锁,请先按 MENU 再按 0。"</string>
<string name="faceunlock_multiple_failures" msgid="754137583022792429">"已超过“人脸解锁”尝试次数上限"</string>
<string name="keyguard_charged" msgid="3272223906073492454">"充电完成"</string>
@@ -62,7 +62,7 @@
<string name="keyguard_accessibility_slide_unlock" msgid="2959928478764697254">"滑动解锁。"</string>
<string name="keyguard_accessibility_pattern_unlock" msgid="1490840706075246612">"图案解锁。"</string>
<string name="keyguard_accessibility_face_unlock" msgid="4817282543351718535">"人脸解锁。"</string>
- <string name="keyguard_accessibility_pin_unlock" msgid="2469687111784035046">"PIN 解锁。"</string>
+ <string name="keyguard_accessibility_pin_unlock" msgid="2469687111784035046">"PIN码解锁。"</string>
<string name="keyguard_accessibility_password_unlock" msgid="7675777623912155089">"密码解锁。"</string>
<string name="keyguard_accessibility_pattern_area" msgid="7679891324509597904">"图案区域。"</string>
<string name="keyguard_accessibility_slide_area" msgid="6736064494019979544">"滑动区域。"</string>
@@ -103,20 +103,20 @@
<string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"忘记了图案"</string>
<string name="kg_wrong_pattern" msgid="1850806070801358830">"图案错误"</string>
<string name="kg_wrong_password" msgid="2333281762128113157">"密码错误"</string>
- <string name="kg_wrong_pin" msgid="1131306510833563801">"PIN 有误"</string>
+ <string name="kg_wrong_pin" msgid="1131306510833563801">"PIN码有误"</string>
<string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"请在 <xliff:g id="NUMBER">%d</xliff:g> 秒后重试。"</string>
<string name="kg_pattern_instructions" msgid="398978611683075868">"绘制您的图案"</string>
<string name="kg_sim_pin_instructions" msgid="2319508550934557331">"输入SIM卡PIN码"</string>
- <string name="kg_pin_instructions" msgid="2377242233495111557">"输入 PIN"</string>
+ <string name="kg_pin_instructions" msgid="2377242233495111557">"输入PIN码"</string>
<string name="kg_password_instructions" msgid="5753646556186936819">"输入密码"</string>
<string name="kg_puk_enter_puk_hint" msgid="453227143861735537">"SIM卡已被停用,需要输入PUK码才能继续使用。有关详情,请联系您的运营商。"</string>
- <string name="kg_puk_enter_pin_hint" msgid="7871604527429602024">"请输入所需 PIN 码"</string>
- <string name="kg_enter_confirm_pin_hint" msgid="325676184762529976">"请确认所需 PIN 码"</string>
+ <string name="kg_puk_enter_pin_hint" msgid="7871604527429602024">"请输入所需的PIN码"</string>
+ <string name="kg_enter_confirm_pin_hint" msgid="325676184762529976">"请确认所需的PIN码"</string>
<string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"正在解锁SIM卡..."</string>
- <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"请输入 4 至 8 位数的 PIN。"</string>
+ <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"请输入4至8位数的PIN码。"</string>
<string name="kg_invalid_sim_puk_hint" msgid="7553388325654369575">"PUK码应至少包含8位数字。"</string>
<string name="kg_invalid_puk" msgid="3638289409676051243">"请重新输入正确的PUK码。如果尝试错误次数过多,SIM卡将永久停用。"</string>
- <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"PIN 码不匹配"</string>
+ <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"PIN码不匹配"</string>
<string name="kg_login_too_many_attempts" msgid="6486842094005698475">"图案尝试次数过多"</string>
<string name="kg_login_instructions" msgid="1100551261265506448">"要解锁,请登录您的Google帐户。"</string>
<string name="kg_login_username_hint" msgid="5718534272070920364">"用户名(电子邮件地址)"</string>
@@ -125,13 +125,13 @@
<string name="kg_login_invalid_input" msgid="5754664119319872197">"用户名或密码无效。"</string>
<string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"忘记了用户名或密码?\n请访问 "<b>"google.com/accounts/recovery"</b>"。"</string>
<string name="kg_login_checking_password" msgid="1052685197710252395">"正在检查帐户…"</string>
- <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"您已经 <xliff:g id="NUMBER_0">%d</xliff:g> 次错误地输入了 PIN。\n\n请在 <xliff:g id="NUMBER_1">%d</xliff:g> 秒后重试。"</string>
+ <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"您已经<xliff:g id="NUMBER_0">%d</xliff:g>次输错了PIN码。\n\n请在<xliff:g id="NUMBER_1">%d</xliff:g>秒后重试。"</string>
<string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"您已经 <xliff:g id="NUMBER_0">%d</xliff:g> 次错误地输入了密码。\n\n请在 <xliff:g id="NUMBER_1">%d</xliff:g> 秒后重试。"</string>
<string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"您已经 <xliff:g id="NUMBER_0">%d</xliff:g> 次错误地绘制了解锁图案。\n\n请在 <xliff:g id="NUMBER_1">%d</xliff:g> 秒后重试。"</string>
- <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"您已经 <xliff:g id="NUMBER_0">%d</xliff:g> 次错误地尝试解锁平板电脑。如果再尝试 <xliff:g id="NUMBER_1">%d</xliff:g> 次后仍不成功,平板电脑就会重置为出厂默认设置,而且所有用户数据都会丢失。"</string>
- <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"您已经 <xliff:g id="NUMBER_0">%d</xliff:g> 次错误地尝试解锁手机。如果再尝试 <xliff:g id="NUMBER_1">%d</xliff:g> 次后仍不成功,手机就会重置为出厂默认设置,而且所有用户数据都会丢失。"</string>
- <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2072996269148483637">"您已经 <xliff:g id="NUMBER">%d</xliff:g> 次错误地尝试解锁平板电脑。平板电脑现在将重置为出厂默认设置。"</string>
- <string name="kg_failed_attempts_now_wiping" product="default" msgid="4817627474419471518">"您已经 <xliff:g id="NUMBER">%d</xliff:g> 次错误地尝试解锁手机。手机现在将重置为出厂默认设置。"</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"您已经<xliff:g id="NUMBER_0">%d</xliff:g>次错误地尝试解锁平板电脑。如果再尝试<xliff:g id="NUMBER_1">%d</xliff:g>次后仍不成功,平板电脑就会恢复为出厂默认设置,而且所有用户数据都会丢失。"</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"您已经<xliff:g id="NUMBER_0">%d</xliff:g>次错误地尝试解锁手机。如果再尝试<xliff:g id="NUMBER_1">%d</xliff:g>次后仍不成功,手机就会恢复为出厂默认设置,而且所有用户数据都会丢失。"</string>
+ <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2072996269148483637">"您已经<xliff:g id="NUMBER">%d</xliff:g>次错误地尝试解锁平板电脑。平板电脑现在将恢复为出厂默认设置。"</string>
+ <string name="kg_failed_attempts_now_wiping" product="default" msgid="4817627474419471518">"您已经<xliff:g id="NUMBER">%d</xliff:g>次错误地尝试解锁手机。手机现在将恢复为出厂默认设置。"</string>
<string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"您已经 <xliff:g id="NUMBER_0">%d</xliff:g> 次错误地绘制了解锁图案。如果再尝试 <xliff:g id="NUMBER_1">%d</xliff:g> 次后仍不成功,系统就会要求您使用自己的电子邮件帐户解锁平板电脑。\n\n请在 <xliff:g id="NUMBER_2">%d</xliff:g> 秒后重试。"</string>
<string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"您已经 <xliff:g id="NUMBER_0">%d</xliff:g> 次错误地绘制了解锁图案。如果再尝试 <xliff:g id="NUMBER_1">%d</xliff:g> 次后仍不成功,系统就会要求您使用自己的电子邮件帐户解锁手机。\n\n请在 <xliff:g id="NUMBER_2">%d</xliff:g> 秒后重试。"</string>
<string name="kg_text_message_separator" product="default" msgid="4160700433287233771">" — "</string>
diff --git a/packages/Keyguard/res/values-zh-rHK/strings.xml b/packages/Keyguard/res/values-zh-rHK/strings.xml
index 064c6df..f196ffd 100644
--- a/packages/Keyguard/res/values-zh-rHK/strings.xml
+++ b/packages/Keyguard/res/values-zh-rHK/strings.xml
@@ -52,7 +52,7 @@
<string name="keyguard_accessibility_unlock_area_expanded" msgid="2278106022311170299">"解鎖區域已展開。"</string>
<string name="keyguard_accessibility_unlock_area_collapsed" msgid="6366992066936076396">"解鎖區域已收合。"</string>
<string name="keyguard_accessibility_widget" msgid="6527131039741808240">"<xliff:g id="WIDGET_INDEX">%1$s</xliff:g>小工具。"</string>
- <string name="keyguard_accessibility_user_selector" msgid="1226798370913698896">"用戶選取工具"</string>
+ <string name="keyguard_accessibility_user_selector" msgid="1226798370913698896">"使用者選取工具"</string>
<string name="keyguard_accessibility_camera" msgid="8904231194181114603">"相機"</string>
<string name="keygaurd_accessibility_media_controls" msgid="262209654292161806">"媒體控制"</string>
<string name="keyguard_accessibility_widget_reorder_start" msgid="8736853615588828197">"已開始為小工具重新排列次序。"</string>
@@ -98,7 +98,7 @@
<string name="description_direction_down" msgid="5087739728639014595">"向下滑動即可<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>。"</string>
<string name="description_direction_left" msgid="7207478719805562165">"向左滑動即可<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>。"</string>
<string name="description_direction_right" msgid="8034433242579600980">"向右滑動即可<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>。"</string>
- <string name="user_switched" msgid="3768006783166984410">"目前的用戶是<xliff:g id="NAME">%1$s</xliff:g>。"</string>
+ <string name="user_switched" msgid="3768006783166984410">"目前的使用者是<xliff:g id="NAME">%1$s</xliff:g>。"</string>
<string name="kg_emergency_call_label" msgid="684946192523830531">"緊急電話"</string>
<string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"忘記圖案"</string>
<string name="kg_wrong_pattern" msgid="1850806070801358830">"圖案錯誤"</string>
@@ -119,17 +119,17 @@
<string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"PIN 碼不符"</string>
<string name="kg_login_too_many_attempts" msgid="6486842094005698475">"圖案嘗試次數過多"</string>
<string name="kg_login_instructions" msgid="1100551261265506448">"如要解鎖,請以 Google 帳戶登入。"</string>
- <string name="kg_login_username_hint" msgid="5718534272070920364">"用戶名稱 (電子郵件)"</string>
+ <string name="kg_login_username_hint" msgid="5718534272070920364">"使用者名稱 (電子郵件)"</string>
<string name="kg_login_password_hint" msgid="9057289103827298549">"密碼"</string>
<string name="kg_login_submit_button" msgid="5355904582674054702">"登入"</string>
- <string name="kg_login_invalid_input" msgid="5754664119319872197">"無效的用戶名稱或密碼。"</string>
- <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"忘記用戶名稱或密碼?\n請瀏覽 "<b>"google.com/accounts/recovery"</b>"。"</string>
+ <string name="kg_login_invalid_input" msgid="5754664119319872197">"無效的使用者名稱或密碼。"</string>
+ <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"忘記使用者名稱或密碼?\n請瀏覽 "<b>"google.com/accounts/recovery"</b>"。"</string>
<string name="kg_login_checking_password" msgid="1052685197710252395">"正在檢查帳戶…"</string>
<string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"您已輸入錯誤的 PIN 碼 <xliff:g id="NUMBER_0">%d</xliff:g> 次。\n\n請在 <xliff:g id="NUMBER_1">%d</xliff:g> 秒後再試一次。"</string>
<string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"您已輸入錯誤的密碼 <xliff:g id="NUMBER_0">%d</xliff:g> 次。\n\n請在 <xliff:g id="NUMBER_1">%d</xliff:g> 秒後再試一次。"</string>
<string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"您已畫錯解鎖圖案 <xliff:g id="NUMBER_0">%d</xliff:g> 次。\n\n請在 <xliff:g id="NUMBER_1">%d</xliff:g> 秒後再試一次。"</string>
- <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"您嘗試了 <xliff:g id="NUMBER_0">%d</xliff:g> 次仍未能成功解開這部上鎖的平板電腦。如果再嘗試 <xliff:g id="NUMBER_1">%d</xliff:g> 次仍未成功,平板電腦將回復原廠設定,所有用戶資料均會失去。"</string>
- <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"您嘗試了 <xliff:g id="NUMBER_0">%d</xliff:g> 次仍未能成功解開這部上鎖的手機。如果再嘗試 <xliff:g id="NUMBER_1">%d</xliff:g> 次仍未成功,手機將回復原廠設定,所有用戶資料均會失去。"</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"您嘗試了 <xliff:g id="NUMBER_0">%d</xliff:g> 次仍未能成功解開這部上鎖的平板電腦。如果再嘗試 <xliff:g id="NUMBER_1">%d</xliff:g> 次仍未成功,平板電腦將回復原廠設定,所有使用者資料均會失去。"</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"您嘗試了 <xliff:g id="NUMBER_0">%d</xliff:g> 次仍未能成功解開這部上鎖的手機。如果再嘗試 <xliff:g id="NUMBER_1">%d</xliff:g> 次仍未成功,手機將回復原廠設定,所有使用者資料均會失去。"</string>
<string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2072996269148483637">"您嘗試了 <xliff:g id="NUMBER">%d</xliff:g> 次仍未能成功解開這部上鎖的平板電腦。平板電腦現在將回復原廠設定。"</string>
<string name="kg_failed_attempts_now_wiping" product="default" msgid="4817627474419471518">"您嘗試了 <xliff:g id="NUMBER">%d</xliff:g> 次仍未能成功解開這部上鎖的手機。手機現在將回復原廠設定。"</string>
<string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"您已畫錯解鎖圖案 <xliff:g id="NUMBER_0">%d</xliff:g> 次,如果再嘗試 <xliff:g id="NUMBER_1">%d</xliff:g> 次仍未成功,系統會要求您透過電郵帳戶解開上鎖的平板電腦。\n\n請在 <xliff:g id="NUMBER_2">%d</xliff:g> 秒後再試一次。"</string>
diff --git a/packages/PrintSpooler/res/values-bn-rBD/strings.xml b/packages/PrintSpooler/res/values-bn-rBD/strings.xml
index 35a7285..5c5fabf 100644
--- a/packages/PrintSpooler/res/values-bn-rBD/strings.xml
+++ b/packages/PrintSpooler/res/values-bn-rBD/strings.xml
@@ -37,6 +37,14 @@
<string name="all_printers" msgid="5018829726861876202">"সমস্ত মুদ্রক…"</string>
<string name="print_dialog" msgid="32628687461331979">"মুদ্রণ ডায়লগ"</string>
<string name="current_page_template" msgid="1386638343571771292">"<xliff:g id="CURRENT_PAGE">%1$d</xliff:g> /<xliff:g id="PAGE_COUNT">%2$d</xliff:g>"</string>
+ <string name="page_description_template" msgid="6831239682256197161">"<xliff:g id="PAGE_COUNT">%2$d</xliff:g>টির মধ্যে <xliff:g id="CURRENT_PAGE">%1$d</xliff:g> নম্বর পৃষ্ঠা"</string>
+ <string name="summary_template" msgid="8899734908625669193">"সারাংশ, <xliff:g id="COPIES">%1$s</xliff:g>টি অনুলিপি, কাগজের আকার <xliff:g id="PAPER_SIZE">%2$s</xliff:g>"</string>
+ <string name="expand_handle" msgid="7282974448109280522">"প্রসারিত করার হ্যান্ডেল"</string>
+ <string name="collapse_handle" msgid="6886637989442507451">"সঙ্কুচিত করার হ্যান্ডেল"</string>
+ <string name="print_button" msgid="645164566271246268">"মুদ্রণ করুন"</string>
+ <string name="savetopdf_button" msgid="2976186791686924743">"PDF হিসাবে সংরক্ষণ করুন"</string>
+ <string name="print_options_expanded" msgid="6944679157471691859">"মুদ্রণ বিকল্প প্রসারিত হয়েছে"</string>
+ <string name="print_options_collapsed" msgid="7455930445670414332">"মুদ্রণ বিকল্প সংকুচিত হয়েছে"</string>
<string name="search" msgid="5421724265322228497">"অনুসন্ধান করুন"</string>
<string name="all_printers_label" msgid="3178848870161526399">"সমস্ত মুদ্রক"</string>
<string name="add_print_service_label" msgid="5356702546188981940">"পরিষেবা যোগ করুন"</string>
diff --git a/packages/PrintSpooler/res/values-eu-rES/strings.xml b/packages/PrintSpooler/res/values-eu-rES/strings.xml
index 69a04ad..4f0f8fc 100644
--- a/packages/PrintSpooler/res/values-eu-rES/strings.xml
+++ b/packages/PrintSpooler/res/values-eu-rES/strings.xml
@@ -37,6 +37,14 @@
<string name="all_printers" msgid="5018829726861876202">"Inprimagailu guztiak…"</string>
<string name="print_dialog" msgid="32628687461331979">"Inprimatzeko elkarrizketa-koadroa"</string>
<string name="current_page_template" msgid="1386638343571771292">"<xliff:g id="CURRENT_PAGE">%1$d</xliff:g>/<xliff:g id="PAGE_COUNT">%2$d</xliff:g>"</string>
+ <string name="page_description_template" msgid="6831239682256197161">"<xliff:g id="CURRENT_PAGE">%1$d</xliff:g>/<xliff:g id="PAGE_COUNT">%2$d</xliff:g> orria"</string>
+ <string name="summary_template" msgid="8899734908625669193">"Laburpena, <xliff:g id="COPIES">%1$s</xliff:g> kopia, <xliff:g id="PAPER_SIZE">%2$s</xliff:g> paper-tamaina"</string>
+ <string name="expand_handle" msgid="7282974448109280522">"Zabaldu heldulekua"</string>
+ <string name="collapse_handle" msgid="6886637989442507451">"Tolestu heldulekua"</string>
+ <string name="print_button" msgid="645164566271246268">"Inprimatu"</string>
+ <string name="savetopdf_button" msgid="2976186791686924743">"Gorde PDF gisa"</string>
+ <string name="print_options_expanded" msgid="6944679157471691859">"Inprimatzeko aukerak zabalduta daude"</string>
+ <string name="print_options_collapsed" msgid="7455930445670414332">"Inprimatzeko aukerak tolestuta daude"</string>
<string name="search" msgid="5421724265322228497">"Bilatu"</string>
<string name="all_printers_label" msgid="3178848870161526399">"Inprimagailu guztiak"</string>
<string name="add_print_service_label" msgid="5356702546188981940">"Gehitu zerbitzua"</string>
diff --git a/packages/PrintSpooler/res/values-gl-rES/strings.xml b/packages/PrintSpooler/res/values-gl-rES/strings.xml
index 9b180cc..6e542ea 100644
--- a/packages/PrintSpooler/res/values-gl-rES/strings.xml
+++ b/packages/PrintSpooler/res/values-gl-rES/strings.xml
@@ -37,6 +37,14 @@
<string name="all_printers" msgid="5018829726861876202">"Todas as impresoras..."</string>
<string name="print_dialog" msgid="32628687461331979">"Diálogo de impresión"</string>
<string name="current_page_template" msgid="1386638343571771292">"<xliff:g id="CURRENT_PAGE">%1$d</xliff:g> /<xliff:g id="PAGE_COUNT">%2$d</xliff:g>"</string>
+ <string name="page_description_template" msgid="6831239682256197161">"Páxina <xliff:g id="CURRENT_PAGE">%1$d</xliff:g> de <xliff:g id="PAGE_COUNT">%2$d</xliff:g>"</string>
+ <string name="summary_template" msgid="8899734908625669193">"Resumo, copias <xliff:g id="COPIES">%1$s</xliff:g>, tamaño do papel <xliff:g id="PAPER_SIZE">%2$s</xliff:g>"</string>
+ <string name="expand_handle" msgid="7282974448109280522">"Amplía a agarradoira"</string>
+ <string name="collapse_handle" msgid="6886637989442507451">"Contrae a agarradoira"</string>
+ <string name="print_button" msgid="645164566271246268">"Imprimir"</string>
+ <string name="savetopdf_button" msgid="2976186791686924743">"Gardar en PDF"</string>
+ <string name="print_options_expanded" msgid="6944679157471691859">"Opcións de impresión ampliadas"</string>
+ <string name="print_options_collapsed" msgid="7455930445670414332">"Opcións de impresión contraídas"</string>
<string name="search" msgid="5421724265322228497">"Buscar"</string>
<string name="all_printers_label" msgid="3178848870161526399">"Todas as impresoras"</string>
<string name="add_print_service_label" msgid="5356702546188981940">"Engadir servizo"</string>
diff --git a/packages/PrintSpooler/res/values-hi/strings.xml b/packages/PrintSpooler/res/values-hi/strings.xml
index 81d3bf9..a3f7fef 100644
--- a/packages/PrintSpooler/res/values-hi/strings.xml
+++ b/packages/PrintSpooler/res/values-hi/strings.xml
@@ -83,7 +83,7 @@
</string-array>
<string name="print_write_error_message" msgid="5787642615179572543">"फ़ाइल पर नहीं लिखा जा सका"</string>
<string name="print_error_default_message" msgid="8602678405502922346">"क्षमा करें, उससे बात नहीं बनी. पुन: प्रयास करें."</string>
- <string name="print_error_retry" msgid="1426421728784259538">"पुनः प्रयास करें"</string>
+ <string name="print_error_retry" msgid="1426421728784259538">"फिर से प्रयास करें"</string>
<string name="print_error_printer_unavailable" msgid="8985614415253203381">"यह प्रिंटर इस समय उपलब्ध नहीं है."</string>
<string name="print_preparing_preview" msgid="3939930735671364712">"पूर्वावलोकन तैयार हो रहा है..."</string>
</resources>
diff --git a/packages/PrintSpooler/res/values-is-rIS/strings.xml b/packages/PrintSpooler/res/values-is-rIS/strings.xml
index d18b8b5..41a047d 100644
--- a/packages/PrintSpooler/res/values-is-rIS/strings.xml
+++ b/packages/PrintSpooler/res/values-is-rIS/strings.xml
@@ -37,6 +37,14 @@
<string name="all_printers" msgid="5018829726861876202">"Allir prentarar…"</string>
<string name="print_dialog" msgid="32628687461331979">"Prentgluggi"</string>
<string name="current_page_template" msgid="1386638343571771292">"<xliff:g id="CURRENT_PAGE">%1$d</xliff:g>/<xliff:g id="PAGE_COUNT">%2$d</xliff:g>"</string>
+ <string name="page_description_template" msgid="6831239682256197161">"Síða <xliff:g id="CURRENT_PAGE">%1$d</xliff:g> af <xliff:g id="PAGE_COUNT">%2$d</xliff:g>"</string>
+ <string name="summary_template" msgid="8899734908625669193">"Yfirlit, <xliff:g id="COPIES">%1$s</xliff:g> eintök, pappírsstærð <xliff:g id="PAPER_SIZE">%2$s</xliff:g>"</string>
+ <string name="expand_handle" msgid="7282974448109280522">"Stækkunarhandfang"</string>
+ <string name="collapse_handle" msgid="6886637989442507451">"Minnkunarhandfang"</string>
+ <string name="print_button" msgid="645164566271246268">"Prenta"</string>
+ <string name="savetopdf_button" msgid="2976186791686924743">"Vista sem PDF"</string>
+ <string name="print_options_expanded" msgid="6944679157471691859">"Prentvalkostir stækkaðir"</string>
+ <string name="print_options_collapsed" msgid="7455930445670414332">"Prentvalkostir minnkaðir"</string>
<string name="search" msgid="5421724265322228497">"Leita"</string>
<string name="all_printers_label" msgid="3178848870161526399">"Allir prentarar"</string>
<string name="add_print_service_label" msgid="5356702546188981940">"Bæta við þjónustu"</string>
diff --git a/packages/PrintSpooler/res/values-kk-rKZ/strings.xml b/packages/PrintSpooler/res/values-kk-rKZ/strings.xml
index 8c6a34fd..b02714b 100644
--- a/packages/PrintSpooler/res/values-kk-rKZ/strings.xml
+++ b/packages/PrintSpooler/res/values-kk-rKZ/strings.xml
@@ -37,6 +37,14 @@
<string name="all_printers" msgid="5018829726861876202">"Барлық принтерлер…"</string>
<string name="print_dialog" msgid="32628687461331979">"Басу терезесі"</string>
<string name="current_page_template" msgid="1386638343571771292">"<xliff:g id="CURRENT_PAGE">%1$d</xliff:g> /<xliff:g id="PAGE_COUNT">%2$d</xliff:g>"</string>
+ <string name="page_description_template" msgid="6831239682256197161">"<xliff:g id="PAGE_COUNT">%2$d</xliff:g> ішінен <xliff:g id="CURRENT_PAGE">%1$d</xliff:g> бет"</string>
+ <string name="summary_template" msgid="8899734908625669193">"Жиынтық мәліметтер, көшірмелер <xliff:g id="COPIES">%1$s</xliff:g>, қағаз өлшемі <xliff:g id="PAPER_SIZE">%2$s</xliff:g>"</string>
+ <string name="expand_handle" msgid="7282974448109280522">"Кеңейту таңбалауышы"</string>
+ <string name="collapse_handle" msgid="6886637989442507451">"Тасалау таңбалауышы"</string>
+ <string name="print_button" msgid="645164566271246268">"Басып шығару"</string>
+ <string name="savetopdf_button" msgid="2976186791686924743">"PDF пішімінде сақтау"</string>
+ <string name="print_options_expanded" msgid="6944679157471691859">"Басып шығару опциялары кеңейтілді"</string>
+ <string name="print_options_collapsed" msgid="7455930445670414332">"Басып шығару опциялары тасаланды"</string>
<string name="search" msgid="5421724265322228497">"Іздеу"</string>
<string name="all_printers_label" msgid="3178848870161526399">"Барлық принтерлер"</string>
<string name="add_print_service_label" msgid="5356702546188981940">"Қызмет қосу"</string>
diff --git a/packages/PrintSpooler/res/values-kn-rIN/strings.xml b/packages/PrintSpooler/res/values-kn-rIN/strings.xml
index 7f848e4..3950866 100644
--- a/packages/PrintSpooler/res/values-kn-rIN/strings.xml
+++ b/packages/PrintSpooler/res/values-kn-rIN/strings.xml
@@ -37,6 +37,14 @@
<string name="all_printers" msgid="5018829726861876202">"ಎಲ್ಲಾ ಮುದ್ರಕಗಳು…"</string>
<string name="print_dialog" msgid="32628687461331979">"ಮುದ್ರಣ ಸಂವಾದ"</string>
<string name="current_page_template" msgid="1386638343571771292">"<xliff:g id="CURRENT_PAGE">%1$d</xliff:g> /<xliff:g id="PAGE_COUNT">%2$d</xliff:g>"</string>
+ <string name="page_description_template" msgid="6831239682256197161">"ಪುಟ <xliff:g id="CURRENT_PAGE">%1$d</xliff:g> / <xliff:g id="PAGE_COUNT">%2$d</xliff:g>"</string>
+ <string name="summary_template" msgid="8899734908625669193">"ಸಾರಾಂಶ, ನಕಲುಗಳು <xliff:g id="COPIES">%1$s</xliff:g>, ಪೇಪರ್ ಗಾತ್ರ <xliff:g id="PAPER_SIZE">%2$s</xliff:g>"</string>
+ <string name="expand_handle" msgid="7282974448109280522">"ಹ್ಯಾಂಡಲ್ ವಿಸ್ತರಿಸಿ"</string>
+ <string name="collapse_handle" msgid="6886637989442507451">"ಹ್ಯಾಂಡಲ್ ಮುಚ್ಚಿರಿ"</string>
+ <string name="print_button" msgid="645164566271246268">"ಮುದ್ರಿಸು"</string>
+ <string name="savetopdf_button" msgid="2976186791686924743">"PDF ಗೆ ಉಳಿಸು"</string>
+ <string name="print_options_expanded" msgid="6944679157471691859">"ಪ್ರಿಂಟ್ ಆಯ್ಕೆಗಳನ್ನು ವಿಸ್ತರಿಸಲಾಗಿದೆ"</string>
+ <string name="print_options_collapsed" msgid="7455930445670414332">"ಪ್ರಿಂಟ್ ಆಯ್ಕೆಗಳನ್ನು ಮುಚ್ಚಲಾಗಿದೆ"</string>
<string name="search" msgid="5421724265322228497">"ಹುಡುಕು"</string>
<string name="all_printers_label" msgid="3178848870161526399">"ಎಲ್ಲಾ ಮುದ್ರಕಗಳು"</string>
<string name="add_print_service_label" msgid="5356702546188981940">"ಸೇವೆಯನ್ನು ಸೇರಿಸು"</string>
diff --git a/packages/PrintSpooler/res/values-ky-rKG/strings.xml b/packages/PrintSpooler/res/values-ky-rKG/strings.xml
index f60f994..602f6605 100644
--- a/packages/PrintSpooler/res/values-ky-rKG/strings.xml
+++ b/packages/PrintSpooler/res/values-ky-rKG/strings.xml
@@ -37,6 +37,14 @@
<string name="all_printers" msgid="5018829726861876202">"Бардык принтерлер…"</string>
<string name="print_dialog" msgid="32628687461331979">"Басуу баарлашуусу"</string>
<string name="current_page_template" msgid="1386638343571771292">"<xliff:g id="CURRENT_PAGE">%1$d</xliff:g> /<xliff:g id="PAGE_COUNT">%2$d</xliff:g>"</string>
+ <string name="page_description_template" msgid="6831239682256197161">"<xliff:g id="PAGE_COUNT">%2$d</xliff:g> ичинен <xliff:g id="CURRENT_PAGE">%1$d</xliff:g>-бет"</string>
+ <string name="summary_template" msgid="8899734908625669193">"Корутунду, <xliff:g id="COPIES">%1$s</xliff:g> көчүрмө, барак өлчөмү <xliff:g id="PAPER_SIZE">%2$s</xliff:g>"</string>
+ <string name="expand_handle" msgid="7282974448109280522">"Тутканы жаюу"</string>
+ <string name="collapse_handle" msgid="6886637989442507451">"Тутканы жыйноо"</string>
+ <string name="print_button" msgid="645164566271246268">"Басуу"</string>
+ <string name="savetopdf_button" msgid="2976186791686924743">"PDF\'ке сактоо"</string>
+ <string name="print_options_expanded" msgid="6944679157471691859">"Басып чыгаруу параметрлери жайылды"</string>
+ <string name="print_options_collapsed" msgid="7455930445670414332">"Басып чыгаруу параметрлери жыйналды"</string>
<string name="search" msgid="5421724265322228497">"Издөө"</string>
<string name="all_printers_label" msgid="3178848870161526399">"Бардык принтерлер"</string>
<string name="add_print_service_label" msgid="5356702546188981940">"Кызматты кошуу"</string>
diff --git a/packages/PrintSpooler/res/values-mk-rMK/strings.xml b/packages/PrintSpooler/res/values-mk-rMK/strings.xml
index eee7c6b..91b5763 100644
--- a/packages/PrintSpooler/res/values-mk-rMK/strings.xml
+++ b/packages/PrintSpooler/res/values-mk-rMK/strings.xml
@@ -37,6 +37,14 @@
<string name="all_printers" msgid="5018829726861876202">"Сите печатачи..."</string>
<string name="print_dialog" msgid="32628687461331979">"Дијалог рамка Печати"</string>
<string name="current_page_template" msgid="1386638343571771292">"<xliff:g id="CURRENT_PAGE">%1$d</xliff:g>/<xliff:g id="PAGE_COUNT">%2$d</xliff:g>"</string>
+ <string name="page_description_template" msgid="6831239682256197161">"Страница <xliff:g id="CURRENT_PAGE">%1$d</xliff:g> од <xliff:g id="PAGE_COUNT">%2$d</xliff:g>"</string>
+ <string name="summary_template" msgid="8899734908625669193">"Краток преглед, копии <xliff:g id="COPIES">%1$s</xliff:g>, големина на хартија <xliff:g id="PAPER_SIZE">%2$s</xliff:g>"</string>
+ <string name="expand_handle" msgid="7282974448109280522">"Рачка за прикажување"</string>
+ <string name="collapse_handle" msgid="6886637989442507451">"Рачка за сокривање"</string>
+ <string name="print_button" msgid="645164566271246268">"Печати"</string>
+ <string name="savetopdf_button" msgid="2976186791686924743">"Зачувај во PDF"</string>
+ <string name="print_options_expanded" msgid="6944679157471691859">"Опциите на печатачот се прикажани"</string>
+ <string name="print_options_collapsed" msgid="7455930445670414332">"Опциите на печатачот се сокриени"</string>
<string name="search" msgid="5421724265322228497">"Пребарај"</string>
<string name="all_printers_label" msgid="3178848870161526399">"Сите печатачи"</string>
<string name="add_print_service_label" msgid="5356702546188981940">"Додај услуга"</string>
diff --git a/packages/PrintSpooler/res/values-ml-rIN/strings.xml b/packages/PrintSpooler/res/values-ml-rIN/strings.xml
index 9093af1..a06ca7d 100644
--- a/packages/PrintSpooler/res/values-ml-rIN/strings.xml
+++ b/packages/PrintSpooler/res/values-ml-rIN/strings.xml
@@ -37,6 +37,14 @@
<string name="all_printers" msgid="5018829726861876202">"എല്ലാ പ്രിന്ററുകളും..."</string>
<string name="print_dialog" msgid="32628687461331979">"പ്രിന്റ് സംഭാഷണം"</string>
<string name="current_page_template" msgid="1386638343571771292">"<xliff:g id="CURRENT_PAGE">%1$d</xliff:g> /<xliff:g id="PAGE_COUNT">%2$d</xliff:g>"</string>
+ <string name="page_description_template" msgid="6831239682256197161">"<xliff:g id="CURRENT_PAGE">%1$d</xliff:g> / <xliff:g id="PAGE_COUNT">%2$d</xliff:g> പേജ്"</string>
+ <string name="summary_template" msgid="8899734908625669193">"സംഗ്രഹം, പകർപ്പുകൾ <xliff:g id="COPIES">%1$s</xliff:g>, പേപ്പർ വലുപ്പം <xliff:g id="PAPER_SIZE">%2$s</xliff:g> എന്നിവ"</string>
+ <string name="expand_handle" msgid="7282974448109280522">"വിപുലീകരണം കൈകാര്യം ചെയ്യുക"</string>
+ <string name="collapse_handle" msgid="6886637989442507451">"ചുരുക്കുന്നത് കൈകാര്യം ചെയ്യുക"</string>
+ <string name="print_button" msgid="645164566271246268">"പ്രിന്റുചെയ്യുക"</string>
+ <string name="savetopdf_button" msgid="2976186791686924743">"PDF-ൽ സംരക്ഷിക്കുക"</string>
+ <string name="print_options_expanded" msgid="6944679157471691859">"പ്രിന്റ് ചെയ്യാനുള്ള ഓപ്ഷനുകൾ വിപുലീകരിച്ചു"</string>
+ <string name="print_options_collapsed" msgid="7455930445670414332">"പ്രിന്റ് ചെയ്യാനുള്ള ഓപ്ഷനുകൾ ചുരുക്കി"</string>
<string name="search" msgid="5421724265322228497">"തിരയൽ"</string>
<string name="all_printers_label" msgid="3178848870161526399">"എല്ലാ പ്രിന്ററുകളും"</string>
<string name="add_print_service_label" msgid="5356702546188981940">"സേവനം ചേർക്കുക"</string>
diff --git a/packages/PrintSpooler/res/values-mr-rIN/strings.xml b/packages/PrintSpooler/res/values-mr-rIN/strings.xml
index 6afe957..1fade66 100644
--- a/packages/PrintSpooler/res/values-mr-rIN/strings.xml
+++ b/packages/PrintSpooler/res/values-mr-rIN/strings.xml
@@ -37,6 +37,14 @@
<string name="all_printers" msgid="5018829726861876202">"सर्व प्रिंटर..."</string>
<string name="print_dialog" msgid="32628687461331979">"मुद्रण संवाद"</string>
<string name="current_page_template" msgid="1386638343571771292">"<xliff:g id="CURRENT_PAGE">%1$d</xliff:g> /<xliff:g id="PAGE_COUNT">%2$d</xliff:g>"</string>
+ <string name="page_description_template" msgid="6831239682256197161">"<xliff:g id="PAGE_COUNT">%2$d</xliff:g> पैकी <xliff:g id="CURRENT_PAGE">%1$d</xliff:g> पृष्ठ"</string>
+ <string name="summary_template" msgid="8899734908625669193">"सारांश, प्रती <xliff:g id="COPIES">%1$s</xliff:g>, कागद आकार <xliff:g id="PAPER_SIZE">%2$s</xliff:g>"</string>
+ <string name="expand_handle" msgid="7282974448109280522">"विस्तृत करण्याचे हँडल"</string>
+ <string name="collapse_handle" msgid="6886637989442507451">"संक्षिप्त करण्याचे हँडल"</string>
+ <string name="print_button" msgid="645164566271246268">"मुद्रण करा"</string>
+ <string name="savetopdf_button" msgid="2976186791686924743">"PDF वर जतन करा"</string>
+ <string name="print_options_expanded" msgid="6944679157471691859">"मुद्रण पर्याय विस्तृत झाले"</string>
+ <string name="print_options_collapsed" msgid="7455930445670414332">"मुद्रण पर्याय संक्षिप्त झाले"</string>
<string name="search" msgid="5421724265322228497">"शोध"</string>
<string name="all_printers_label" msgid="3178848870161526399">"सर्व प्रिंटर"</string>
<string name="add_print_service_label" msgid="5356702546188981940">"सेवा जोडा"</string>
diff --git a/packages/PrintSpooler/res/values-my-rMM/strings.xml b/packages/PrintSpooler/res/values-my-rMM/strings.xml
index 04da765..7dce459 100644
--- a/packages/PrintSpooler/res/values-my-rMM/strings.xml
+++ b/packages/PrintSpooler/res/values-my-rMM/strings.xml
@@ -37,6 +37,14 @@
<string name="all_printers" msgid="5018829726861876202">"စာထုတ်စက် အားလုံး"</string>
<string name="print_dialog" msgid="32628687461331979">"စာထုတ်ရန် အချက်ပြခြင်း"</string>
<string name="current_page_template" msgid="1386638343571771292">"<xliff:g id="CURRENT_PAGE">%1$d</xliff:g> /<xliff:g id="PAGE_COUNT">%2$d</xliff:g>"</string>
+ <string name="page_description_template" msgid="6831239682256197161">"<xliff:g id="PAGE_COUNT">%2$d</xliff:g>ထဲက စာမျက်နှာ <xliff:g id="CURRENT_PAGE">%1$d</xliff:g>"</string>
+ <string name="summary_template" msgid="8899734908625669193">"အကျဉ်းချုပ်၊ ကော်ပီများ<xliff:g id="COPIES">%1$s</xliff:g>၊ စက္ကူ ဆိုက် <xliff:g id="PAPER_SIZE">%2$s</xliff:g>"</string>
+ <string name="expand_handle" msgid="7282974448109280522">"ချဲ့ရန် လက်"</string>
+ <string name="collapse_handle" msgid="6886637989442507451">"ခေါက်ရန် လက်"</string>
+ <string name="print_button" msgid="645164566271246268">"စာထုတ်ရန်"</string>
+ <string name="savetopdf_button" msgid="2976186791686924743">"PDF သို့ သိမ်းဆည်းခဲ့"</string>
+ <string name="print_options_expanded" msgid="6944679157471691859">"ပရင့်ထုတ် ရွေးစရာများကို ချဲ့ထား"</string>
+ <string name="print_options_collapsed" msgid="7455930445670414332">"ပရင့်ထုတ် ရွေးစရာများကို ခေါက်ထား"</string>
<string name="search" msgid="5421724265322228497">"ရှာဖွေခြင်း"</string>
<string name="all_printers_label" msgid="3178848870161526399">"စာထုတ်စက် အားလုံး"</string>
<string name="add_print_service_label" msgid="5356702546188981940">"ဆားဗစ် အသစ်ထည့်ရန်"</string>
@@ -77,5 +85,5 @@
<string name="print_error_default_message" msgid="8602678405502922346">"ဆော်ရီး၊ အဲဒါ အလုပ်မဖြစ်ခဲ့ပါ။ ထပ် စမ်းပါ။"</string>
<string name="print_error_retry" msgid="1426421728784259538">"ထပ်စမ်း"</string>
<string name="print_error_printer_unavailable" msgid="8985614415253203381">"ဒီပရင်တာမှာ ယခုအချိန်မှာ မရနိုင်ပါ။"</string>
- <string name="print_preparing_preview" msgid="3939930735671364712">"အစမ်းကြည့်ရန် ပြင်ဆင်နေ…"</string>
+ <string name="print_preparing_preview" msgid="3939930735671364712">"အစမ်းကြည့်ရန် ပြင်ဆင်နေ…"</string>
</resources>
diff --git a/packages/PrintSpooler/res/values-ne-rNP/strings.xml b/packages/PrintSpooler/res/values-ne-rNP/strings.xml
index 110f698..eb97530 100644
--- a/packages/PrintSpooler/res/values-ne-rNP/strings.xml
+++ b/packages/PrintSpooler/res/values-ne-rNP/strings.xml
@@ -37,6 +37,14 @@
<string name="all_printers" msgid="5018829726861876202">"सबै प्रिन्टरहरू..."</string>
<string name="print_dialog" msgid="32628687461331979">"सम्वाद छाप्नुहोस्"</string>
<string name="current_page_template" msgid="1386638343571771292">"<xliff:g id="CURRENT_PAGE">%1$d</xliff:g> /<xliff:g id="PAGE_COUNT">%2$d</xliff:g>"</string>
+ <string name="page_description_template" msgid="6831239682256197161">"<xliff:g id="PAGE_COUNT">%2$d</xliff:g> को <xliff:g id="CURRENT_PAGE">%1$d</xliff:g> पृष्ठ"</string>
+ <string name="summary_template" msgid="8899734908625669193">"सारांश, प्रतिहरू <xliff:g id="COPIES">%1$s</xliff:g> , कागज आकार <xliff:g id="PAPER_SIZE">%2$s</xliff:g>"</string>
+ <string name="expand_handle" msgid="7282974448109280522">"ह्यान्डल विस्तार गर्नुहोस्"</string>
+ <string name="collapse_handle" msgid="6886637989442507451">"ह्यान्डल कोल्याप्स गर्नुहोस्"</string>
+ <string name="print_button" msgid="645164566271246268">"प्रिन्ट गर्नुहोस्"</string>
+ <string name="savetopdf_button" msgid="2976186791686924743">"PDF सुरक्षित गर्नुहोस्"</string>
+ <string name="print_options_expanded" msgid="6944679157471691859">"विस्तार गरेका विकल्पहरू प्रिन्ट गर्नुहोस्"</string>
+ <string name="print_options_collapsed" msgid="7455930445670414332">"कोल्याप्स गरेका विकल्पहरू प्रिन्ट गर्नुहोस्"</string>
<string name="search" msgid="5421724265322228497">"खोज्नुहोस्"</string>
<string name="all_printers_label" msgid="3178848870161526399">"सबै प्रिन्टरहरू"</string>
<string name="add_print_service_label" msgid="5356702546188981940">"सेवा थप्नुहोस्"</string>
diff --git a/packages/PrintSpooler/res/values-si-rLK/strings.xml b/packages/PrintSpooler/res/values-si-rLK/strings.xml
index f6cc5e2..386ce8d 100644
--- a/packages/PrintSpooler/res/values-si-rLK/strings.xml
+++ b/packages/PrintSpooler/res/values-si-rLK/strings.xml
@@ -37,6 +37,14 @@
<string name="all_printers" msgid="5018829726861876202">"සියලු මුද්රණ යන්ත්ර…"</string>
<string name="print_dialog" msgid="32628687461331979">"මුද්රණ සංවාද කොටුව"</string>
<string name="current_page_template" msgid="1386638343571771292">"<xliff:g id="CURRENT_PAGE">%1$d</xliff:g> /<xliff:g id="PAGE_COUNT">%2$d</xliff:g>"</string>
+ <string name="page_description_template" msgid="6831239682256197161">"පිටු <xliff:g id="PAGE_COUNT">%2$d</xliff:g> න් <xliff:g id="CURRENT_PAGE">%1$d</xliff:g>"</string>
+ <string name="summary_template" msgid="8899734908625669193">"සාරාංශය, පිටපත් <xliff:g id="COPIES">%1$s</xliff:g>, පිටුවේ ප්රමණය <xliff:g id="PAPER_SIZE">%2$s</xliff:g>"</string>
+ <string name="expand_handle" msgid="7282974448109280522">"විහිදන මිට"</string>
+ <string name="collapse_handle" msgid="6886637989442507451">"හකුළන මිට"</string>
+ <string name="print_button" msgid="645164566271246268">"මුද්රණය කරන්න"</string>
+ <string name="savetopdf_button" msgid="2976186791686924743">"PDF වෙත සුරකින්න"</string>
+ <string name="print_options_expanded" msgid="6944679157471691859">"විහිදන ලද විකල්ප මුද්රණය කරන්න"</string>
+ <string name="print_options_collapsed" msgid="7455930445670414332">"හකුළන ලද විකල්ප මුද්රණය කරන්න"</string>
<string name="search" msgid="5421724265322228497">"සෙවීම"</string>
<string name="all_printers_label" msgid="3178848870161526399">"සියලු මුද්රණ යන්ත්ර"</string>
<string name="add_print_service_label" msgid="5356702546188981940">"සේවාව එක් කිරීම"</string>
diff --git a/packages/PrintSpooler/res/values-ta-rIN/strings.xml b/packages/PrintSpooler/res/values-ta-rIN/strings.xml
index 39eead8..0421bd6 100644
--- a/packages/PrintSpooler/res/values-ta-rIN/strings.xml
+++ b/packages/PrintSpooler/res/values-ta-rIN/strings.xml
@@ -37,6 +37,14 @@
<string name="all_printers" msgid="5018829726861876202">"எல்லா அச்சுப்பொறிகளும்…"</string>
<string name="print_dialog" msgid="32628687461331979">"அச்சிடல் செய்தி"</string>
<string name="current_page_template" msgid="1386638343571771292">"<xliff:g id="CURRENT_PAGE">%1$d</xliff:g> /<xliff:g id="PAGE_COUNT">%2$d</xliff:g>"</string>
+ <string name="page_description_template" msgid="6831239682256197161">"பக்கம்: <xliff:g id="CURRENT_PAGE">%1$d</xliff:g> / <xliff:g id="PAGE_COUNT">%2$d</xliff:g>"</string>
+ <string name="summary_template" msgid="8899734908625669193">"சுருக்கம், நகல்கள் <xliff:g id="COPIES">%1$s</xliff:g>, தாள் அளவு <xliff:g id="PAPER_SIZE">%2$s</xliff:g>"</string>
+ <string name="expand_handle" msgid="7282974448109280522">"ஹேண்டிலை விரிவாக்கு"</string>
+ <string name="collapse_handle" msgid="6886637989442507451">"ஹேண்டிலைச் சுருக்கு"</string>
+ <string name="print_button" msgid="645164566271246268">"அச்சிடு"</string>
+ <string name="savetopdf_button" msgid="2976186791686924743">"PDF ஆகச் சேமி"</string>
+ <string name="print_options_expanded" msgid="6944679157471691859">"அச்சு விருப்பங்கள் விரிவாக்கப்பட்டன"</string>
+ <string name="print_options_collapsed" msgid="7455930445670414332">"அச்சு விருப்பங்கள் சுருக்கப்பட்டன"</string>
<string name="search" msgid="5421724265322228497">"தேடு"</string>
<string name="all_printers_label" msgid="3178848870161526399">"எல்லா அச்சுப்பொறிகளும்"</string>
<string name="add_print_service_label" msgid="5356702546188981940">"சேவையைச் சேர்"</string>
diff --git a/packages/PrintSpooler/res/values-te-rIN/strings.xml b/packages/PrintSpooler/res/values-te-rIN/strings.xml
index 3ad4d1d..edb6e60 100644
--- a/packages/PrintSpooler/res/values-te-rIN/strings.xml
+++ b/packages/PrintSpooler/res/values-te-rIN/strings.xml
@@ -37,6 +37,14 @@
<string name="all_printers" msgid="5018829726861876202">"అన్ని ప్రింటర్లు…"</string>
<string name="print_dialog" msgid="32628687461331979">"ముద్రణ డైలాగ్"</string>
<string name="current_page_template" msgid="1386638343571771292">"<xliff:g id="CURRENT_PAGE">%1$d</xliff:g> /<xliff:g id="PAGE_COUNT">%2$d</xliff:g>"</string>
+ <string name="page_description_template" msgid="6831239682256197161">"<xliff:g id="PAGE_COUNT">%2$d</xliff:g>లో <xliff:g id="CURRENT_PAGE">%1$d</xliff:g>వ పేజీ"</string>
+ <string name="summary_template" msgid="8899734908625669193">"సారాంశం, కాపీలు <xliff:g id="COPIES">%1$s</xliff:g>, కాగితం పరిమాణం <xliff:g id="PAPER_SIZE">%2$s</xliff:g>"</string>
+ <string name="expand_handle" msgid="7282974448109280522">"విస్తరణ హ్యాండిల్"</string>
+ <string name="collapse_handle" msgid="6886637989442507451">"కుదింపు హ్యాండిల్"</string>
+ <string name="print_button" msgid="645164566271246268">"ముద్రించు"</string>
+ <string name="savetopdf_button" msgid="2976186791686924743">"PDF వలె సేవ్ చేయి"</string>
+ <string name="print_options_expanded" msgid="6944679157471691859">"ముద్రణ ఎంపికలు విస్తరించబడ్డాయి"</string>
+ <string name="print_options_collapsed" msgid="7455930445670414332">"ముద్రణ ఎంపికలు కుదించబడ్డాయి"</string>
<string name="search" msgid="5421724265322228497">"శోధించు"</string>
<string name="all_printers_label" msgid="3178848870161526399">"అన్ని ప్రింటర్లు"</string>
<string name="add_print_service_label" msgid="5356702546188981940">"సేవను జోడించు"</string>
diff --git a/packages/PrintSpooler/res/values-ur-rPK/strings.xml b/packages/PrintSpooler/res/values-ur-rPK/strings.xml
index 1ff57a7..722d027 100644
--- a/packages/PrintSpooler/res/values-ur-rPK/strings.xml
+++ b/packages/PrintSpooler/res/values-ur-rPK/strings.xml
@@ -37,6 +37,14 @@
<string name="all_printers" msgid="5018829726861876202">"سبھی پرنٹرز…"</string>
<string name="print_dialog" msgid="32628687461331979">"پرنٹ ڈائلاگ"</string>
<string name="current_page_template" msgid="1386638343571771292">"<xliff:g id="CURRENT_PAGE">%1$d</xliff:g> /<xliff:g id="PAGE_COUNT">%2$d</xliff:g>"</string>
+ <string name="page_description_template" msgid="6831239682256197161">"صفحہ <xliff:g id="CURRENT_PAGE">%1$d</xliff:g> از <xliff:g id="PAGE_COUNT">%2$d</xliff:g>"</string>
+ <string name="summary_template" msgid="8899734908625669193">"خلاصہ، کاپیاں <xliff:g id="COPIES">%1$s</xliff:g>، کاغذ کا سائز <xliff:g id="PAPER_SIZE">%2$s</xliff:g>"</string>
+ <string name="expand_handle" msgid="7282974448109280522">"پھیلانے والا ہینڈل"</string>
+ <string name="collapse_handle" msgid="6886637989442507451">"سکیڑنے والا ہینڈل"</string>
+ <string name="print_button" msgid="645164566271246268">"پرنٹ کریں"</string>
+ <string name="savetopdf_button" msgid="2976186791686924743">"PDF میں محفوظ کریں"</string>
+ <string name="print_options_expanded" msgid="6944679157471691859">"پرنٹ کے اختیارات پھیلا دیے گئے"</string>
+ <string name="print_options_collapsed" msgid="7455930445670414332">"پرنٹ کے اختیارات سکیڑ دیے گئے"</string>
<string name="search" msgid="5421724265322228497">"تلاش کریں"</string>
<string name="all_printers_label" msgid="3178848870161526399">"سبھی پرنٹرز"</string>
<string name="add_print_service_label" msgid="5356702546188981940">"سروس شامل کریں"</string>
diff --git a/packages/PrintSpooler/res/values-uz-rUZ/strings.xml b/packages/PrintSpooler/res/values-uz-rUZ/strings.xml
index 8ab3410..f62728f 100644
--- a/packages/PrintSpooler/res/values-uz-rUZ/strings.xml
+++ b/packages/PrintSpooler/res/values-uz-rUZ/strings.xml
@@ -37,6 +37,14 @@
<string name="all_printers" msgid="5018829726861876202">"Barcha printerlar…"</string>
<string name="print_dialog" msgid="32628687461331979">"Chop etish oynasi"</string>
<string name="current_page_template" msgid="1386638343571771292">"<xliff:g id="CURRENT_PAGE">%1$d</xliff:g> /<xliff:g id="PAGE_COUNT">%2$d</xliff:g>"</string>
+ <string name="page_description_template" msgid="6831239682256197161">"Sahifa: <xliff:g id="CURRENT_PAGE">%1$d</xliff:g>/<xliff:g id="PAGE_COUNT">%2$d</xliff:g>"</string>
+ <string name="summary_template" msgid="8899734908625669193">"Xulosa: nusxalar soni – <xliff:g id="COPIES">%1$s</xliff:g>, qog‘oz o‘lchami – <xliff:g id="PAPER_SIZE">%2$s</xliff:g>"</string>
+ <string name="expand_handle" msgid="7282974448109280522">"Dastakni yoyish"</string>
+ <string name="collapse_handle" msgid="6886637989442507451">"Dastakni yig‘ish"</string>
+ <string name="print_button" msgid="645164566271246268">"Chop etish"</string>
+ <string name="savetopdf_button" msgid="2976186791686924743">"PDF sifatida saqlash"</string>
+ <string name="print_options_expanded" msgid="6944679157471691859">"Chop qilish tanlamalari yoyildi"</string>
+ <string name="print_options_collapsed" msgid="7455930445670414332">"Chop qilish tanlamalari yig‘ildi"</string>
<string name="search" msgid="5421724265322228497">"Izlash"</string>
<string name="all_printers_label" msgid="3178848870161526399">"Barcha printerlar"</string>
<string name="add_print_service_label" msgid="5356702546188981940">"Xizmat qo‘shish"</string>
diff --git a/packages/SettingsProvider/res/values-hi/strings.xml b/packages/SettingsProvider/res/values-hi/strings.xml
index 0b0bd8a..da8193f 100644
--- a/packages/SettingsProvider/res/values-hi/strings.xml
+++ b/packages/SettingsProvider/res/values-hi/strings.xml
@@ -19,5 +19,5 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_label" msgid="4567566098528588863">"सेटिंग संग्रहण"</string>
+ <string name="app_label" msgid="4567566098528588863">"सेटिंग मेमोरी"</string>
</resources>
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java b/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
index ddf24e8..1771eac 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
@@ -2614,6 +2614,9 @@
// Set default cdma call auto retry
loadSetting(stmt, Settings.Global.CALL_AUTO_RETRY, 0);
+ // Set default simplified carrier network settings to 0
+ loadSetting(stmt, Settings.Global.HIDE_CARRIER_NETWORK_SETTINGS, 0);
+
// Set the preferred network mode to target desired value or Default
// value defined in RILConstants
int type;
diff --git a/packages/Shell/res/values-cs/strings.xml b/packages/Shell/res/values-cs/strings.xml
index 10ef1a6c..d321159 100644
--- a/packages/Shell/res/values-cs/strings.xml
+++ b/packages/Shell/res/values-cs/strings.xml
@@ -16,7 +16,7 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_label" msgid="3701846017049540910">"Prostředí"</string>
+ <string name="app_label" msgid="3701846017049540910">"Shell"</string>
<string name="bugreport_finished_title" msgid="2293711546892863898">"Bylo vytvořeno chybové hlášení"</string>
<string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"Chcete-li hlášení chyby sdílet, přejeďte doleva."</string>
<string name="bugreport_finished_text" product="default" msgid="3559904746859400732">"Chybové hlášení můžete sdílet klepnutím."</string>
diff --git a/packages/Shell/res/values-es/strings.xml b/packages/Shell/res/values-es/strings.xml
index c9a9bfa..19bfc25 100644
--- a/packages/Shell/res/values-es/strings.xml
+++ b/packages/Shell/res/values-es/strings.xml
@@ -17,7 +17,7 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="3701846017049540910">"Shell"</string>
- <string name="bugreport_finished_title" msgid="2293711546892863898">"Informe de error capturado"</string>
+ <string name="bugreport_finished_title" msgid="2293711546892863898">"Informe de error registrado"</string>
<string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"Desliza el dedo hacia la izquierda para compartir el informe de error"</string>
<string name="bugreport_finished_text" product="default" msgid="3559904746859400732">"Toca para compartir tu informe de error"</string>
<string name="bugreport_confirm" msgid="5130698467795669780">"Los informes de errores contienen datos de los distintos archivos de registro del sistema, incluida información personal y privada. Comparte los informes de errores únicamente con aplicaciones y usuarios en los que confíes."</string>
diff --git a/packages/Shell/res/values-lt/strings.xml b/packages/Shell/res/values-lt/strings.xml
index 914ef46..a78b1db 100644
--- a/packages/Shell/res/values-lt/strings.xml
+++ b/packages/Shell/res/values-lt/strings.xml
@@ -17,9 +17,9 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="3701846017049540910">"Apvalkalas"</string>
- <string name="bugreport_finished_title" msgid="2293711546892863898">"Trikčių ataskaita užfiksuota"</string>
- <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"Perbraukite kairėn, kad bendrintumėte trikties ataskaitą"</string>
- <string name="bugreport_finished_text" product="default" msgid="3559904746859400732">"Palieskite, kad bendrintumėte trikčių ataskaitą"</string>
- <string name="bugreport_confirm" msgid="5130698467795669780">"Trikčių ataskaitose pateikiami duomenys iš įvairių sistemos žurnalo failų, įskaitant asmeninę ir privačią informaciją. Trikčių ataskaitas bendrinkite tik su patikimomis programomis ir žmonėmis."</string>
+ <string name="bugreport_finished_title" msgid="2293711546892863898">"Riktų ataskaita užfiksuota"</string>
+ <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"Perbraukite kairėn, kad bendrintumėte rikto ataskaitą"</string>
+ <string name="bugreport_finished_text" product="default" msgid="3559904746859400732">"Palieskite, kad bendrintumėte riktų ataskaitą"</string>
+ <string name="bugreport_confirm" msgid="5130698467795669780">"Riktų ataskaitose pateikiami duomenys iš įvairių sistemos žurnalo failų, įskaitant asmeninę ir privačią informaciją. Riktų ataskaitas bendrinkite tik su patikimomis programomis ir žmonėmis."</string>
<string name="bugreport_confirm_repeat" msgid="4926842460688645058">"Rodyti šį pranešimą kitą kartą"</string>
</resources>
diff --git a/packages/Shell/res/values-pt/strings.xml b/packages/Shell/res/values-pt/strings.xml
index 3d4c51f..c166bf3 100644
--- a/packages/Shell/res/values-pt/strings.xml
+++ b/packages/Shell/res/values-pt/strings.xml
@@ -20,6 +20,6 @@
<string name="bugreport_finished_title" msgid="2293711546892863898">"Relatório de bugs capturado"</string>
<string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"Deslize para a esquerda para compartilhar seu relatório de bugs"</string>
<string name="bugreport_finished_text" product="default" msgid="3559904746859400732">"Toque para compartilhar seu relatório de bugs"</string>
- <string name="bugreport_confirm" msgid="5130698467795669780">"Os relatórios de bugs contêm dados de diversos arquivos de registro do sistema, inclusive informações pessoais e particulares. Compartilhe relatórios de bugs somente com aplicativos e pessoas nos quais você confia."</string>
+ <string name="bugreport_confirm" msgid="5130698467795669780">"Os relatórios de bugs contêm dados de diversos arquivos de registro do sistema, inclusive informações pessoais e particulares. Compartilhe relatórios de bugs somente com apps e pessoas nos quais você confia."</string>
<string name="bugreport_confirm_repeat" msgid="4926842460688645058">"Mostrar esta mensagem da próxima vez"</string>
</resources>
diff --git a/packages/Shell/res/values-ru/strings.xml b/packages/Shell/res/values-ru/strings.xml
index 7c80736..77a8cd0 100644
--- a/packages/Shell/res/values-ru/strings.xml
+++ b/packages/Shell/res/values-ru/strings.xml
@@ -17,8 +17,8 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="3701846017049540910">"Оболочка"</string>
- <string name="bugreport_finished_title" msgid="2293711546892863898">"Отчет об ошибках сохранен"</string>
- <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"Проведите пальцем влево, чтобы отправить отчет об ошибке"</string>
+ <string name="bugreport_finished_title" msgid="2293711546892863898">"Отчет об ошибке сохранен"</string>
+ <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"Проведите влево, чтобы отправить отчет"</string>
<string name="bugreport_finished_text" product="default" msgid="3559904746859400732">"Нажмите, чтобы отправить отчет об ошибках"</string>
<string name="bugreport_confirm" msgid="5130698467795669780">"Отчеты об ошибках содержат данные различных системных журналов и могут включать личную информацию. Рекомендуем открывать к ним доступ только лицам и приложениям, заслуживающим доверие."</string>
<string name="bugreport_confirm_repeat" msgid="4926842460688645058">"Показать это сообщение в следующий раз"</string>
diff --git a/packages/Shell/res/values-zh-rHK/strings.xml b/packages/Shell/res/values-zh-rHK/strings.xml
index 0d56d76..f2e034b 100644
--- a/packages/Shell/res/values-zh-rHK/strings.xml
+++ b/packages/Shell/res/values-zh-rHK/strings.xml
@@ -20,6 +20,6 @@
<string name="bugreport_finished_title" msgid="2293711546892863898">"已擷取錯誤報告"</string>
<string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"向左滑動即可分享錯誤報告"</string>
<string name="bugreport_finished_text" product="default" msgid="3559904746859400732">"輕觸即可分享您的錯誤報告"</string>
- <string name="bugreport_confirm" msgid="5130698467795669780">"錯誤報告中有來自系統各個記錄檔案的資料,包括個人和私人資料。請只與您信任的應用程式和用戶分享錯誤報告。"</string>
+ <string name="bugreport_confirm" msgid="5130698467795669780">"錯誤報告中有來自系統各個記錄檔案的資料,包括個人和私人資料。請只與您信任的應用程式和使用者分享錯誤報告。"</string>
<string name="bugreport_confirm_repeat" msgid="4926842460688645058">"下次再顯示這則訊息"</string>
</resources>
diff --git a/packages/SystemUI/src/com/android/systemui/EventLogTags.logtags b/packages/SystemUI/src/com/android/systemui/EventLogTags.logtags
index 5f2c348..6337956 100644
--- a/packages/SystemUI/src/com/android/systemui/EventLogTags.logtags
+++ b/packages/SystemUI/src/com/android/systemui/EventLogTags.logtags
@@ -7,6 +7,8 @@
# ---------------------------
36000 sysui_statusbar_touch (type|1),(x|1),(y|1),(enabled|1)
36001 sysui_heads_up_status (key|3),(visible|1)
+36002 sysui_fullscreen_notification (key|3)
+36003 sysui_heads_up_escalation (key|3)
# ---------------------------
# PhoneStatusBarView.java
diff --git a/packages/SystemUI/src/com/android/systemui/SwipeHelper.java b/packages/SystemUI/src/com/android/systemui/SwipeHelper.java
index f206e56..33f6564 100644
--- a/packages/SystemUI/src/com/android/systemui/SwipeHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/SwipeHelper.java
@@ -453,7 +453,8 @@
&& !mTouchAboveFalsingThreshold;
boolean dismissChild = mCallback.canChildBeDismissed(mCurrView)
- && !falsingDetected && (childSwipedFastEnough || childSwipedFarEnough);
+ && !falsingDetected && (childSwipedFastEnough || childSwipedFarEnough)
+ && ev.getActionMasked() == MotionEvent.ACTION_UP;
if (dismissChild) {
// flingadingy
diff --git a/packages/SystemUI/src/com/android/systemui/recent/RecentsHorizontalScrollView.java b/packages/SystemUI/src/com/android/systemui/recent/RecentsHorizontalScrollView.java
index 330333a..cf5d3a6 100644
--- a/packages/SystemUI/src/com/android/systemui/recent/RecentsHorizontalScrollView.java
+++ b/packages/SystemUI/src/com/android/systemui/recent/RecentsHorizontalScrollView.java
@@ -23,7 +23,6 @@
import android.graphics.Canvas;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
-import android.util.FloatMath;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
@@ -368,7 +367,7 @@
View child = mAdapter.createView(mLinearLayout);
child.measure(childWidthMeasureSpec, childheightMeasureSpec);
mNumItemsInOneScreenful =
- (int) FloatMath.ceil(dm.widthPixels / (float) child.getMeasuredWidth());
+ (int) Math.ceil(dm.widthPixels / (double) child.getMeasuredWidth());
addToRecycledViews(child);
for (int i = 0; i < mNumItemsInOneScreenful - 1; i++) {
diff --git a/packages/SystemUI/src/com/android/systemui/recent/RecentsVerticalScrollView.java b/packages/SystemUI/src/com/android/systemui/recent/RecentsVerticalScrollView.java
index 1e247be..d518f74 100644
--- a/packages/SystemUI/src/com/android/systemui/recent/RecentsVerticalScrollView.java
+++ b/packages/SystemUI/src/com/android/systemui/recent/RecentsVerticalScrollView.java
@@ -23,7 +23,6 @@
import android.graphics.Canvas;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
-import android.util.FloatMath;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
@@ -378,7 +377,7 @@
View child = mAdapter.createView(mLinearLayout);
child.measure(childWidthMeasureSpec, childheightMeasureSpec);
mNumItemsInOneScreenful =
- (int) FloatMath.ceil(dm.heightPixels / (float) child.getMeasuredHeight());
+ (int) Math.ceil(dm.heightPixels / (double) child.getMeasuredHeight());
addToRecycledViews(child);
for (int i = 0; i < mNumItemsInOneScreenful - 1; i++) {
diff --git a/packages/SystemUI/src/com/android/systemui/recents/AlternateRecentsComponent.java b/packages/SystemUI/src/com/android/systemui/recents/AlternateRecentsComponent.java
index 2bfdb69..b5a6dac 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/AlternateRecentsComponent.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/AlternateRecentsComponent.java
@@ -41,6 +41,7 @@
import com.android.systemui.RecentsComponent;
import com.android.systemui.recents.misc.Console;
import com.android.systemui.recents.misc.SystemServicesProxy;
+import com.android.systemui.recents.model.RecentsTaskLoadPlan;
import com.android.systemui.recents.model.RecentsTaskLoader;
import com.android.systemui.recents.model.Task;
import com.android.systemui.recents.model.TaskGrouping;
@@ -64,6 +65,8 @@
final public static String EXTRA_TRIGGERED_FROM_ALT_TAB = "recents.triggeredFromAltTab";
final public static String EXTRA_TRIGGERED_FROM_HOME_KEY = "recents.triggeredFromHomeKey";
final public static String EXTRA_REUSE_TASK_STACK_VIEWS = "recents.reuseTaskStackViews";
+ final public static String EXTRA_NUM_VISIBLE_TASKS = "recents.numVisibleTasks";
+ final public static String EXTRA_NUM_VISIBLE_THUMBNAILS = "recents.numVisibleThumbnails";
final public static String ACTION_START_ENTER_ANIMATION = "action_start_enter_animation";
final public static String ACTION_TOGGLE_RECENTS_ACTIVITY = "action_toggle_recents_activity";
@@ -76,6 +79,7 @@
final static String sRecentsActivity = "com.android.systemui.recents.RecentsActivity";
static RecentsComponent.Callbacks sRecentsComponentCallbacks;
+ static RecentsTaskLoadPlan sInstanceLoadPlan;
Context mContext;
LayoutInflater mInflater;
@@ -134,8 +138,15 @@
}
}
- // When we start, preload the metadata associated with the previous tasks
- RecentsTaskLoader.getInstance().preload(mContext, RecentsTaskLoader.ALL_TASKS);
+ // When we start, preload the metadata and icons associated with the recent tasks.
+ // We can use a new plan since the caches will be the same.
+ RecentsTaskLoader loader = RecentsTaskLoader.getInstance();
+ RecentsTaskLoadPlan plan = loader.createLoadPlan(mContext);
+ loader.preloadTasks(plan, true /* isTopTaskHome */);
+ RecentsTaskLoadPlan.Options launchOpts = new RecentsTaskLoadPlan.Options();
+ launchOpts.numVisibleTasks = loader.getApplicationIconCacheSize();
+ launchOpts.loadThumbnails = false;
+ loader.loadTasks(mContext, plan, launchOpts);
}
public void onBootCompleted() {
@@ -183,9 +194,11 @@
}
public void onPreloadRecents() {
- // When we start, preload the metadata associated with the previous tasks
- RecentsTaskLoader.getInstance().preload(mContext,
- Constants.Values.RecentsTaskLoader.PreloadFirstTasksCount);
+ // Preload only the raw task list into a new load plan (which will be consumed by the
+ // RecentsActivity)
+ RecentsTaskLoader loader = RecentsTaskLoader.getInstance();
+ sInstanceLoadPlan = loader.createLoadPlan(mContext);
+ sInstanceLoadPlan.preloadRawTasks(true);
}
public void onCancelPreloadingRecents() {
@@ -194,8 +207,10 @@
void showRelativeAffiliatedTask(boolean showNextTask) {
RecentsTaskLoader loader = RecentsTaskLoader.getInstance();
- TaskStack stack = loader.getTaskStack(mSystemServicesProxy, mContext.getResources(),
- -1, -1, RecentsTaskLoader.ALL_TASKS, false, true, null, null);
+ RecentsTaskLoadPlan plan = loader.createLoadPlan(mContext);
+ loader.preloadTasks(plan, true /* isTopTaskHome */);
+ TaskStack stack = plan.getTaskStack();
+
// Return early if there are no tasks
if (stack.getTaskCount() == 0) return;
@@ -411,11 +426,11 @@
* Creates the activity options for an app->recents transition.
*/
ActivityOptions getThumbnailTransitionActivityOptions(ActivityManager.RunningTaskInfo topTask,
- boolean isTopTaskHome) {
+ TaskStack stack, TaskStackView stackView) {
// Update the destination rect
Task toTask = new Task();
- TaskViewTransform toTransform = getThumbnailTransitionTransform(topTask.id, isTopTaskHome,
- toTask);
+ TaskViewTransform toTransform = getThumbnailTransitionTransform(stack, stackView,
+ topTask.id, toTask);
if (toTransform != null && toTask.key != null) {
Rect toTaskRect = toTransform.rect;
int toHeaderWidth = (int) (mHeaderBar.getMeasuredWidth() * toTransform.scale);
@@ -443,16 +458,8 @@
}
/** Returns the transition rect for the given task id. */
- TaskViewTransform getThumbnailTransitionTransform(int runningTaskId, boolean isTopTaskHome,
- Task runningTaskOut) {
- // Get the stack of tasks that we are animating into
- RecentsTaskLoader loader = RecentsTaskLoader.getInstance();
- TaskStack stack = loader.getTaskStack(mSystemServicesProxy, mContext.getResources(),
- runningTaskId, -1, RecentsTaskLoader.ALL_TASKS, false, isTopTaskHome, null, null);
- if (stack.getTaskCount() == 0) {
- return null;
- }
-
+ TaskViewTransform getThumbnailTransitionTransform(TaskStack stack, TaskStackView stackView,
+ int runningTaskId, Task runningTaskOut) {
// Find the running task in the TaskStack
Task task = null;
ArrayList<Task> tasks = stack.getTasks();
@@ -474,30 +481,42 @@
}
// Get the transform for the running task
- mDummyStackView.updateMinMaxScrollForStack(stack, mTriggeredFromAltTab, isTopTaskHome);
- mDummyStackView.getScroller().setStackScrollToInitialState();
- mTmpTransform = mDummyStackView.getStackAlgorithm().getStackTransform(task,
- mDummyStackView.getScroller().getStackScroll(), mTmpTransform, null);
+ stackView.getScroller().setStackScrollToInitialState();
+ mTmpTransform = stackView.getStackAlgorithm().getStackTransform(task,
+ stackView.getScroller().getStackScroll(), mTmpTransform, null);
return mTmpTransform;
}
/** Starts the recents activity */
void startRecentsActivity(ActivityManager.RunningTaskInfo topTask, boolean isTopTaskHome) {
- // If Recents is not the front-most activity and we should animate into it. If
- // the activity at the root of the top task stack in the home stack, then we just do a
- // simple transition. Otherwise, we animate to the rects defined by the Recents service,
- // which can differ depending on the number of items in the list.
- SystemServicesProxy ssp = mSystemServicesProxy;
- List<ActivityManager.RecentTaskInfo> recentTasks =
- ssp.getRecentTasks(3, UserHandle.CURRENT.getIdentifier(), isTopTaskHome);
- boolean useThumbnailTransition = !isTopTaskHome;
- boolean hasRecentTasks = !recentTasks.isEmpty();
+ if (sInstanceLoadPlan == null) {
+ // Create a new load plan if onPreloadRecents() was never triggered
+ RecentsTaskLoader loader = RecentsTaskLoader.getInstance();
+ sInstanceLoadPlan = loader.createLoadPlan(mContext);
+ }
+ RecentsTaskLoader loader = RecentsTaskLoader.getInstance();
+ loader.preloadTasks(sInstanceLoadPlan, isTopTaskHome);
+ TaskStack stack = sInstanceLoadPlan.getTaskStack();
+
+ // Prepare the dummy stack for the transition
+ mDummyStackView.updateMinMaxScrollForStack(stack, mTriggeredFromAltTab, isTopTaskHome);
+ TaskStackViewLayoutAlgorithm.VisibilityReport stackVr =
+ mDummyStackView.computeStackVisibilityReport();
+ boolean hasRecentTasks = stack.getTaskCount() > 0;
+ boolean useThumbnailTransition = !isTopTaskHome && hasRecentTasks;
if (useThumbnailTransition) {
+ // Ensure that we load the running task's icon
+ RecentsTaskLoadPlan.Options launchOpts = new RecentsTaskLoadPlan.Options();
+ launchOpts.runningTaskId = topTask.id;
+ launchOpts.loadThumbnails = false;
+ loader.loadTasks(mContext, sInstanceLoadPlan, launchOpts);
+
// Try starting with a thumbnail transition
- ActivityOptions opts = getThumbnailTransitionActivityOptions(topTask, isTopTaskHome);
+ ActivityOptions opts = getThumbnailTransitionActivityOptions(topTask, stack,
+ mDummyStackView);
if (opts != null) {
- startAlternateRecentsActivity(topTask, opts, EXTRA_FROM_APP_THUMBNAIL);
+ startAlternateRecentsActivity(topTask, opts, EXTRA_FROM_APP_THUMBNAIL, stackVr);
} else {
// Fall through below to the non-thumbnail transition
useThumbnailTransition = false;
@@ -531,11 +550,11 @@
ActivityOptions opts = getHomeTransitionActivityOptions(fromSearchHome);
startAlternateRecentsActivity(topTask, opts,
- fromSearchHome ? EXTRA_FROM_SEARCH_HOME : EXTRA_FROM_HOME);
+ fromSearchHome ? EXTRA_FROM_SEARCH_HOME : EXTRA_FROM_HOME, stackVr);
} else {
// Otherwise we do the normal fade from an unknown source
ActivityOptions opts = getUnknownTransitionActivityOptions();
- startAlternateRecentsActivity(topTask, opts, EXTRA_FROM_HOME);
+ startAlternateRecentsActivity(topTask, opts, EXTRA_FROM_HOME, stackVr);
}
}
mLastToggleTime = System.currentTimeMillis();
@@ -543,7 +562,8 @@
/** Starts the recents activity */
void startAlternateRecentsActivity(ActivityManager.RunningTaskInfo topTask,
- ActivityOptions opts, String extraFlag) {
+ ActivityOptions opts, String extraFlag,
+ TaskStackViewLayoutAlgorithm.VisibilityReport vr) {
Intent intent = new Intent(sToggleRecentsAction);
intent.setClassName(sRecentsPackage, sRecentsActivity);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
@@ -555,6 +575,8 @@
intent.putExtra(EXTRA_TRIGGERED_FROM_ALT_TAB, mTriggeredFromAltTab);
intent.putExtra(EXTRA_FROM_TASK_ID, (topTask != null) ? topTask.id : -1);
intent.putExtra(EXTRA_REUSE_TASK_STACK_VIEWS, mCanReuseTaskStackViews);
+ intent.putExtra(EXTRA_NUM_VISIBLE_TASKS, vr.numVisibleTasks);
+ intent.putExtra(EXTRA_NUM_VISIBLE_THUMBNAILS, vr.numVisibleThumbnails);
if (opts != null) {
mContext.startActivityAsUser(intent, opts.toBundle(), UserHandle.CURRENT);
} else {
@@ -575,6 +597,15 @@
}
}
+ /**
+ * Returns the preloaded load plan and invalidates it.
+ */
+ public static RecentsTaskLoadPlan consumeInstanceLoadPlan() {
+ RecentsTaskLoadPlan plan = sInstanceLoadPlan;
+ sInstanceLoadPlan = null;
+ return plan;
+ }
+
/**** OnAnimationStartedListener Implementation ****/
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/recents/Constants.java b/packages/SystemUI/src/com/android/systemui/recents/Constants.java
index 9b84d2e..4c76af7 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/Constants.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/Constants.java
@@ -64,11 +64,6 @@
public static String DebugModeVersion = "A";
}
- public static class RecentsTaskLoader {
- // XXX: This should be calculated on the first load
- public static final int PreloadFirstTasksCount = 6;
- }
-
public static class TaskStackView {
public static final int TaskStackOverscrollRange = 150;
public static final int FilterStartDelay = 25;
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
index de95ae8..9a7fec4 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
@@ -27,10 +27,7 @@
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
-import android.content.res.Configuration;
import android.os.Bundle;
-import android.os.Handler;
-import android.os.Looper;
import android.os.UserHandle;
import android.util.Pair;
import android.view.KeyEvent;
@@ -43,6 +40,7 @@
import com.android.systemui.recents.misc.ReferenceCountedTrigger;
import com.android.systemui.recents.misc.SystemServicesProxy;
import com.android.systemui.recents.misc.Utilities;
+import com.android.systemui.recents.model.RecentsTaskLoadPlan;
import com.android.systemui.recents.model.RecentsTaskLoader;
import com.android.systemui.recents.model.SpaceNode;
import com.android.systemui.recents.model.Task;
@@ -168,9 +166,10 @@
if (action.equals(Intent.ACTION_SCREEN_OFF)) {
// When the screen turns off, dismiss Recents to Home
dismissRecentsToHome(false);
- // Start preloading some tasks in the background
- RecentsTaskLoader.getInstance().preload(RecentsActivity.this,
- Constants.Values.RecentsTaskLoader.PreloadFirstTasksCount);
+ // Preload the metadata for all tasks in the background
+ RecentsTaskLoader loader = RecentsTaskLoader.getInstance();
+ RecentsTaskLoadPlan plan = loader.createLoadPlan(context);
+ loader.preloadTasks(plan, true /* isTopTaskHome */);
} else if (action.equals(SearchManager.INTENT_GLOBAL_SEARCH_ACTIVITY_CHANGED)) {
// When the search activity changes, update the Search widget
refreshSearchWidget();
@@ -193,6 +192,10 @@
// Update the configuration based on the launch intent
boolean fromSearchHome = launchIntent.getBooleanExtra(
AlternateRecentsComponent.EXTRA_FROM_SEARCH_HOME, false);
+ int numVisibleTasks = launchIntent.getIntExtra(
+ AlternateRecentsComponent.EXTRA_NUM_VISIBLE_TASKS, 0);
+ int numVisibleThumbnails = launchIntent.getIntExtra(
+ AlternateRecentsComponent.EXTRA_NUM_VISIBLE_THUMBNAILS, 0);
mConfig.launchedFromHome = fromSearchHome || launchIntent.getBooleanExtra(
AlternateRecentsComponent.EXTRA_FROM_HOME, false);
mConfig.launchedFromAppWithThumbnail = launchIntent.getBooleanExtra(
@@ -204,16 +207,29 @@
mConfig.launchedReuseTaskStackViews = launchIntent.getBooleanExtra(
AlternateRecentsComponent.EXTRA_REUSE_TASK_STACK_VIEWS, false);
- // Load all the tasks
+ // If AlternateRecentsComponent has preloaded a load plan, then use that to prevent
+ // reconstructing the task stack
RecentsTaskLoader loader = RecentsTaskLoader.getInstance();
- SpaceNode root = loader.reload(this,
- Constants.Values.RecentsTaskLoader.PreloadFirstTasksCount,
- mConfig.launchedFromHome);
- ArrayList<TaskStack> stacks = root.getStacks();
- if (!stacks.isEmpty()) {
- mRecentsView.setTaskStacks(root.getStacks());
+ RecentsTaskLoadPlan plan = AlternateRecentsComponent.consumeInstanceLoadPlan();
+ if (plan == null) {
+ plan = loader.createLoadPlan(this);
+ loader.preloadTasks(plan, mConfig.launchedFromHome);
}
- mConfig.launchedWithNoRecentTasks = !root.hasTasks();
+
+ // Start loading tasks according to the load plan
+ RecentsTaskLoadPlan.Options loadOpts = new RecentsTaskLoadPlan.Options();
+ loadOpts.runningTaskId = mConfig.launchedToTaskId;
+ loadOpts.numVisibleTasks = numVisibleTasks;
+ loadOpts.numVisibleTaskThumbnails = numVisibleThumbnails;
+ loader.loadTasks(this, plan, loadOpts);
+
+ SpaceNode root = plan.getSpaceNode();
+ ArrayList<TaskStack> stacks = root.getStacks();
+ boolean hasTasks = root.hasTasks();
+ if (hasTasks) {
+ mRecentsView.setTaskStacks(stacks);
+ }
+ mConfig.launchedWithNoRecentTasks = !hasTasks;
// Create the home intent runnable
Intent homeIntent = new Intent(Intent.ACTION_MAIN, null);
@@ -442,6 +458,8 @@
/** Inflates the debug overlay if debug mode is enabled. */
void inflateDebugOverlay() {
+ if (!Constants.DebugFlags.App.EnableDebugMode) return;
+
if (mConfig.debugModeEnabled && mDebugOverlay == null) {
// Inflate the overlay and seek bars
mDebugOverlay = (DebugOverlayView) mDebugOverlayStub.inflate();
@@ -600,13 +618,17 @@
settings.edit().remove(Constants.Values.App.Key_DebugModeEnabled).apply();
mConfig.debugModeEnabled = false;
inflateDebugOverlay();
- mDebugOverlay.disable();
+ if (mDebugOverlay != null) {
+ mDebugOverlay.disable();
+ }
} else {
// Enable the debug mode
settings.edit().putBoolean(Constants.Values.App.Key_DebugModeEnabled, true).apply();
mConfig.debugModeEnabled = true;
inflateDebugOverlay();
- mDebugOverlay.enable();
+ if (mDebugOverlay != null) {
+ mDebugOverlay.enable();
+ }
}
Toast.makeText(this, "Debug mode (" + Constants.Values.App.DebugModeVersion + ") " +
(mConfig.debugModeEnabled ? "Enabled" : "Disabled") + ", please restart Recents now",
diff --git a/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java b/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java
index 51b3fb5..9a4bd08 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java
@@ -244,6 +244,7 @@
Bitmap thumbnail = SystemServicesProxy.getThumbnail(mAm, taskId);
if (thumbnail != null) {
+ thumbnail.setHasAlpha(false);
// We use a dumb heuristic for now, if the thumbnail is purely transparent in the top
// left pixel, then assume the whole thumbnail is transparent. Generally, proper
// screenshots are always composed onto a bitmap that has no alpha.
diff --git a/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoadPlan.java b/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoadPlan.java
new file mode 100644
index 0000000..41251c8
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoadPlan.java
@@ -0,0 +1,224 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.recents.model;
+
+import android.app.ActivityManager;
+import android.content.Context;
+import android.content.res.Resources;
+import android.graphics.Bitmap;
+import android.graphics.drawable.Drawable;
+import android.os.UserHandle;
+import android.util.Log;
+import com.android.systemui.recents.RecentsConfiguration;
+import com.android.systemui.recents.misc.SystemServicesProxy;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+
+
+/**
+ * This class stores the loading state as it goes through multiple stages of loading:
+ * - preloadRawTasks() will load the raw set of recents tasks from the system
+ * - preloadPlan() will construct a new task stack with all metadata and only icons and thumbnails
+ * that are currently in the cache
+ * - executePlan() will actually load and fill in the icons and thumbnails according to the load
+ * options specified, such that we can transition into the Recents activity seamlessly
+ */
+public class RecentsTaskLoadPlan {
+ static String TAG = "RecentsTaskLoadPlan";
+ static boolean DEBUG = false;
+
+ /** The set of conditions to load tasks. */
+ public static class Options {
+ public int runningTaskId = -1;
+ public boolean loadIcons = true;
+ public boolean loadThumbnails = true;
+ public int numVisibleTasks = 0;
+ public int numVisibleTaskThumbnails = 0;
+ }
+
+ Context mContext;
+ RecentsConfiguration mConfig;
+ SystemServicesProxy mSystemServicesProxy;
+
+ List<ActivityManager.RecentTaskInfo> mRawTasks;
+ TaskStack mStack;
+ HashMap<Task.ComponentNameKey, ActivityInfoHandle> mActivityInfoCache =
+ new HashMap<Task.ComponentNameKey, ActivityInfoHandle>();
+
+ /** Package level ctor */
+ RecentsTaskLoadPlan(Context context, RecentsConfiguration config, SystemServicesProxy ssp) {
+ mContext = context;
+ mConfig = config;
+ mSystemServicesProxy = ssp;
+ }
+
+ /**
+ * An optimization to preload the raw list of tasks.
+ */
+ public synchronized void preloadRawTasks(boolean isTopTaskHome) {
+ mRawTasks = mSystemServicesProxy.getRecentTasks(mConfig.maxNumTasksToLoad,
+ UserHandle.CURRENT.getIdentifier(), isTopTaskHome);
+ Collections.reverse(mRawTasks);
+
+ if (DEBUG) Log.d(TAG, "preloadRawTasks, tasks: " + mRawTasks.size());
+ }
+
+ /**
+ * Preloads the list of recent tasks from the system. After this call, the TaskStack will
+ * have a list of all the recent tasks with their metadata, not including icons or
+ * thumbnails which were not cached and have to be loaded.
+ */
+ synchronized void preloadPlan(RecentsTaskLoader loader, boolean isTopTaskHome) {
+ if (DEBUG) Log.d(TAG, "preloadPlan");
+
+ mActivityInfoCache.clear();
+ mStack = new TaskStack();
+
+ Resources res = mContext.getResources();
+ ArrayList<Task> loadedTasks = new ArrayList<Task>();
+ if (mRawTasks == null) {
+ preloadRawTasks(isTopTaskHome);
+ }
+ int taskCount = mRawTasks.size();
+ for (int i = 0; i < taskCount; i++) {
+ ActivityManager.RecentTaskInfo t = mRawTasks.get(i);
+
+ // Compose the task key
+ Task.TaskKey taskKey = new Task.TaskKey(t.persistentId, t.baseIntent, t.userId,
+ t.firstActiveTime, t.lastActiveTime);
+
+ // Get an existing activity info handle if possible
+ Task.ComponentNameKey cnKey = taskKey.getComponentNameKey();
+ ActivityInfoHandle infoHandle;
+ boolean hadCachedActivityInfo = false;
+ if (mActivityInfoCache.containsKey(cnKey)) {
+ infoHandle = mActivityInfoCache.get(cnKey);
+ hadCachedActivityInfo = true;
+ } else {
+ infoHandle = new ActivityInfoHandle();
+ }
+
+ // Load the label, icon, and color
+ String activityLabel = loader.getAndUpdateActivityLabel(taskKey, t.taskDescription,
+ mSystemServicesProxy, infoHandle);
+ Drawable activityIcon = loader.getAndUpdateActivityIcon(taskKey, t.taskDescription,
+ mSystemServicesProxy, res, infoHandle, false);
+ int activityColor = loader.getActivityPrimaryColor(t.taskDescription, mConfig);
+
+ // Update the activity info cache
+ if (!hadCachedActivityInfo && infoHandle.info != null) {
+ mActivityInfoCache.put(cnKey, infoHandle);
+ }
+
+ Bitmap icon = t.taskDescription != null
+ ? t.taskDescription.getInMemoryIcon()
+ : null;
+ String iconFilename = t.taskDescription != null
+ ? t.taskDescription.getIconFilename()
+ : null;
+
+ // Add the task to the stack
+ Task task = new Task(taskKey, (t.id != RecentsTaskLoader.INVALID_TASK_ID),
+ t.affiliatedTaskId, t.affiliatedTaskColor, activityLabel, activityIcon,
+ activityColor, (i == (taskCount - 1)), mConfig.lockToAppEnabled, icon,
+ iconFilename);
+ task.thumbnail = loader.getAndUpdateThumbnail(taskKey, mSystemServicesProxy, false);
+ loadedTasks.add(task);
+ }
+ mStack.setTasks(loadedTasks);
+ mStack.createAffiliatedGroupings(mConfig);
+
+ // Assertion
+ if (mStack.getTaskCount() != mRawTasks.size()) {
+ throw new RuntimeException("Loading failed");
+ }
+ }
+
+ /**
+ * Called to apply the actual loading based on the specified conditions.
+ */
+ synchronized void executePlan(Options opts, RecentsTaskLoader loader) {
+ if (DEBUG) Log.d(TAG, "executePlan, # tasks: " + opts.numVisibleTasks +
+ ", # thumbnails: " + opts.numVisibleTaskThumbnails +
+ ", running task id: " + opts.runningTaskId);
+
+ Resources res = mContext.getResources();
+
+ // Iterate through each of the tasks and load them according to the load conditions.
+ ArrayList<Task> tasks = mStack.getTasks();
+ int taskCount = tasks.size();
+ for (int i = 0; i < taskCount; i++) {
+ ActivityManager.RecentTaskInfo t = mRawTasks.get(i);
+ Task task = tasks.get(i);
+ Task.TaskKey taskKey = task.key;
+
+ // Get an existing activity info handle if possible
+ Task.ComponentNameKey cnKey = taskKey.getComponentNameKey();
+ ActivityInfoHandle infoHandle;
+ boolean hadCachedActivityInfo = false;
+ if (mActivityInfoCache.containsKey(cnKey)) {
+ infoHandle = mActivityInfoCache.get(cnKey);
+ hadCachedActivityInfo = true;
+ } else {
+ infoHandle = new ActivityInfoHandle();
+ }
+
+ boolean isRunningTask = (task.key.id == opts.runningTaskId);
+ boolean isVisibleTask = i >= (taskCount - opts.numVisibleTasks);
+ boolean isVisibleThumbnail = i >= (taskCount - opts.numVisibleTaskThumbnails);
+
+ if (opts.loadIcons && (isRunningTask || isVisibleTask)) {
+ if (task.activityIcon == null) {
+ if (DEBUG) Log.d(TAG, "\tLoading icon: " + taskKey);
+ task.activityIcon = loader.getAndUpdateActivityIcon(taskKey, t.taskDescription,
+ mSystemServicesProxy, res, infoHandle, true);
+ }
+ }
+ if (opts.loadThumbnails && (isRunningTask || isVisibleThumbnail)) {
+ if (task.thumbnail == null) {
+ if (DEBUG) Log.d(TAG, "\tLoading thumbnail: " + taskKey);
+ task.thumbnail = loader.getAndUpdateThumbnail(taskKey, mSystemServicesProxy,
+ true);
+ }
+ }
+
+ // Update the activity info cache
+ if (!hadCachedActivityInfo && infoHandle.info != null) {
+ mActivityInfoCache.put(cnKey, infoHandle);
+ }
+ }
+ }
+
+ /**
+ * Composes and returns a TaskStack from the preloaded list of recent tasks.
+ */
+ public TaskStack getTaskStack() {
+ return mStack;
+ }
+
+ /**
+ * Composes and returns a SpaceNode from the preloaded list of recent tasks.
+ */
+ public SpaceNode getSpaceNode() {
+ SpaceNode node = new SpaceNode();
+ node.setStack(mStack);
+ return node;
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoader.java b/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoader.java
index 390507f..6fd738d 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoader.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoader.java
@@ -26,7 +26,6 @@
import android.graphics.drawable.Drawable;
import android.os.Handler;
import android.os.HandlerThread;
-import android.os.UserHandle;
import android.util.Log;
import com.android.systemui.R;
@@ -34,11 +33,7 @@
import com.android.systemui.recents.RecentsConfiguration;
import com.android.systemui.recents.misc.SystemServicesProxy;
-import java.util.ArrayList;
import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
import java.util.concurrent.ConcurrentLinkedQueue;
@@ -205,9 +200,7 @@
// Load the thumbnail if it is stale or we haven't cached one yet
if (cachedThumbnail == null) {
cachedThumbnail = ssp.getTaskThumbnail(t.key.id);
- if (cachedThumbnail != null) {
- cachedThumbnail.setHasAlpha(false);
- } else {
+ if (cachedThumbnail == null) {
cachedThumbnail = mDefaultThumbnail;
}
mThumbnailCache.put(t.key, cachedThumbnail);
@@ -260,7 +253,7 @@
private static final String TAG = "RecentsTaskLoader";
static RecentsTaskLoader sInstance;
- public static final int ALL_TASKS = -1;
+ static int INVALID_TASK_ID = -1;
SystemServicesProxy mSystemServicesProxy;
DrawableLruCache mApplicationIconCache;
@@ -273,6 +266,7 @@
int mMaxThumbnailCacheSize;
int mMaxIconCacheSize;
+ int mNumVisibleTasksLoaded;
BitmapDrawable mDefaultApplicationIcon;
Bitmap mDefaultThumbnail;
@@ -325,55 +319,6 @@
return mSystemServicesProxy;
}
- /** Gets the list of recent tasks, ordered from back to front. */
- private static List<ActivityManager.RecentTaskInfo> getRecentTasks(SystemServicesProxy ssp,
- int numTasksToLoad, boolean isTopTaskHome) {
- List<ActivityManager.RecentTaskInfo> tasks =
- ssp.getRecentTasks(numTasksToLoad, UserHandle.CURRENT.getIdentifier(),
- isTopTaskHome);
- Collections.reverse(tasks);
- return tasks;
- }
-
- /** Returns the activity icon using as many cached values as we can. */
- public Drawable getAndUpdateActivityIcon(Task.TaskKey taskKey,
- ActivityManager.TaskDescription td, SystemServicesProxy ssp,
- Resources res, ActivityInfoHandle infoHandle, boolean preloadTask) {
- // Return the cached activity icon if it exists
- Drawable icon = mApplicationIconCache.getAndInvalidateIfModified(taskKey);
- if (icon != null) {
- return icon;
- }
-
- // If we are preloading this task, continue to load the task description icon or the
- // activity icon
- if (preloadTask) {
-
- // Return and cache the task description icon if it exists
- Drawable tdDrawable = mLoader.getTaskDescriptionIcon(taskKey, td.getInMemoryIcon(),
- td.getIconFilename(), ssp, res);
- if (tdDrawable != null) {
- mApplicationIconCache.put(taskKey, tdDrawable);
- return tdDrawable;
- }
-
- // Load the icon from the activity info and cache it
- if (infoHandle.info == null) {
- infoHandle.info = ssp.getActivityInfo(taskKey.baseIntent.getComponent(),
- taskKey.userId);
- }
- if (infoHandle.info != null) {
- icon = ssp.getActivityIcon(infoHandle.info, taskKey.userId);
- if (icon != null) {
- mApplicationIconCache.put(taskKey, icon);
- return icon;
- }
- }
- }
- // If we couldn't load any icon, return null
- return null;
- }
-
/** Returns the activity label using as many cached values as we can. */
public String getAndUpdateActivityLabel(Task.TaskKey taskKey,
ActivityManager.TaskDescription td, SystemServicesProxy ssp,
@@ -402,6 +347,63 @@
return label;
}
+ /** Returns the activity icon using as many cached values as we can. */
+ public Drawable getAndUpdateActivityIcon(Task.TaskKey taskKey,
+ ActivityManager.TaskDescription td, SystemServicesProxy ssp,
+ Resources res, ActivityInfoHandle infoHandle, boolean loadIfNotCached) {
+ // Return the cached activity icon if it exists
+ Drawable icon = mApplicationIconCache.getAndInvalidateIfModified(taskKey);
+ if (icon != null) {
+ return icon;
+ }
+
+ if (loadIfNotCached) {
+ // Return and cache the task description icon if it exists
+ Drawable tdDrawable = mLoader.getTaskDescriptionIcon(taskKey, td.getInMemoryIcon(),
+ td.getIconFilename(), ssp, res);
+ if (tdDrawable != null) {
+ mApplicationIconCache.put(taskKey, tdDrawable);
+ return tdDrawable;
+ }
+
+ // Load the icon from the activity info and cache it
+ if (infoHandle.info == null) {
+ infoHandle.info = ssp.getActivityInfo(taskKey.baseIntent.getComponent(),
+ taskKey.userId);
+ }
+ if (infoHandle.info != null) {
+ icon = ssp.getActivityIcon(infoHandle.info, taskKey.userId);
+ if (icon != null) {
+ mApplicationIconCache.put(taskKey, icon);
+ return icon;
+ }
+ }
+ }
+ // We couldn't load any icon
+ return null;
+ }
+
+ /** Returns the bitmap using as many cached values as we can. */
+ public Bitmap getAndUpdateThumbnail(Task.TaskKey taskKey, SystemServicesProxy ssp,
+ boolean loadIfNotCached) {
+ // Return the cached thumbnail if it exists
+ Bitmap thumbnail = mThumbnailCache.getAndInvalidateIfModified(taskKey);
+ if (thumbnail != null) {
+ return thumbnail;
+ }
+
+ if (loadIfNotCached) {
+ // Load the thumbnail from the system
+ thumbnail = ssp.getTaskThumbnail(taskKey.id);
+ if (thumbnail != null) {
+ mThumbnailCache.put(taskKey, thumbnail);
+ return thumbnail;
+ }
+ }
+ // We couldn't load any thumbnail
+ return null;
+ }
+
/** Returns the activity's primary color. */
public int getActivityPrimaryColor(ActivityManager.TaskDescription td,
RecentsConfiguration config) {
@@ -411,127 +413,33 @@
return config.taskBarViewDefaultBackgroundColor;
}
- /** Reload the set of recent tasks */
- public SpaceNode reload(Context context, int preloadCount, boolean isTopTaskHome) {
- ArrayList<Task.TaskKey> taskKeys = new ArrayList<Task.TaskKey>();
- ArrayList<Task> tasksToLoad = new ArrayList<Task>();
- TaskStack stack = getTaskStack(mSystemServicesProxy, context.getResources(),
- -1, preloadCount, RecentsTaskLoader.ALL_TASKS, true, isTopTaskHome, taskKeys,
- tasksToLoad);
- SpaceNode root = new SpaceNode();
- root.setStack(stack);
-
- // Start the task loader and add all the tasks we need to load
- mLoadQueue.addTasks(tasksToLoad);
- mLoader.start(context);
-
- return root;
+ /** Returns the size of the app icon cache. */
+ public int getApplicationIconCacheSize() {
+ return mMaxIconCacheSize;
}
- /** Preloads the set of recent tasks (not including thumbnails). */
- public void preload(Context context, int numTasksToPreload) {
- ArrayList<Task> tasksToLoad = new ArrayList<Task>();
- getTaskStack(mSystemServicesProxy, context.getResources(),
- -1, -1, numTasksToPreload, true, true, null, tasksToLoad);
-
- // Start the task loader and add all the tasks we need to load
- mLoadQueue.addTasks(tasksToLoad);
- mLoader.start(context);
- }
-
- /** Creates a lightweight stack of the current recent tasks, without thumbnails and icons. */
- public synchronized TaskStack getTaskStack(SystemServicesProxy ssp, Resources res,
- int preloadTaskId, int preloadTaskCount, int loadTaskCount,
- boolean loadTaskThumbnails, boolean isTopTaskHome,
- List<Task.TaskKey> taskKeysOut, List<Task> tasksToLoadOut) {
+ public RecentsTaskLoadPlan createLoadPlan(Context context) {
RecentsConfiguration config = RecentsConfiguration.getInstance();
- List<ActivityManager.RecentTaskInfo> tasks = getRecentTasks(ssp,
- (loadTaskCount == ALL_TASKS ? config.maxNumTasksToLoad : loadTaskCount),
- isTopTaskHome);
- HashMap<Task.ComponentNameKey, ActivityInfoHandle> activityInfoCache =
- new HashMap<Task.ComponentNameKey, ActivityInfoHandle>();
- ArrayList<Task> tasksToAdd = new ArrayList<Task>();
- TaskStack stack = new TaskStack();
+ RecentsTaskLoadPlan plan = new RecentsTaskLoadPlan(context, config, mSystemServicesProxy);
+ return plan;
+ }
- int taskCount = tasks.size();
- for (int i = 0; i < taskCount; i++) {
- ActivityManager.RecentTaskInfo t = tasks.get(i);
+ public void preloadTasks(RecentsTaskLoadPlan plan, boolean isTopTaskHome) {
+ plan.preloadPlan(this, isTopTaskHome);
+ }
- // Compose the task key
- Task.TaskKey taskKey = new Task.TaskKey(t.persistentId, t.baseIntent, t.userId,
- t.firstActiveTime, t.lastActiveTime);
-
- // Get an existing activity info handle if possible
- Task.ComponentNameKey cnKey = taskKey.getComponentNameKey();
- ActivityInfoHandle infoHandle;
- boolean hasCachedActivityInfo = false;
- if (activityInfoCache.containsKey(cnKey)) {
- infoHandle = activityInfoCache.get(cnKey);
- hasCachedActivityInfo = true;
- } else {
- infoHandle = new ActivityInfoHandle();
- }
-
- // Determine whether to preload this task
- boolean preloadTask = false;
- if (preloadTaskId > 0) {
- preloadTask = (t.id == preloadTaskId);
- } else if (preloadTaskCount > 0) {
- preloadTask = (i >= (taskCount - preloadTaskCount));
- }
-
- // Load the label, icon, and color
- String activityLabel = getAndUpdateActivityLabel(taskKey, t.taskDescription,
- ssp, infoHandle);
- Drawable activityIcon = getAndUpdateActivityIcon(taskKey, t.taskDescription,
- ssp, res, infoHandle, preloadTask);
- int activityColor = getActivityPrimaryColor(t.taskDescription, config);
-
- // Update the activity info cache
- if (!hasCachedActivityInfo && infoHandle.info != null) {
- activityInfoCache.put(cnKey, infoHandle);
- }
-
- Bitmap icon = t.taskDescription != null
- ? t.taskDescription.getInMemoryIcon()
- : null;
- String iconFilename = t.taskDescription != null
- ? t.taskDescription.getIconFilename()
- : null;
-
- // Add the task to the stack
- Task task = new Task(taskKey, (t.id > -1), t.affiliatedTaskId, t.affiliatedTaskColor,
- activityLabel, activityIcon, activityColor, (i == (taskCount - 1)),
- config.lockToAppEnabled, icon, iconFilename);
-
- if (preloadTask && loadTaskThumbnails) {
- // Load the thumbnail from the cache if possible
- task.thumbnail = mThumbnailCache.getAndInvalidateIfModified(taskKey);
- if (task.thumbnail == null) {
- // Load the thumbnail from the system
- task.thumbnail = ssp.getTaskThumbnail(taskKey.id);
- if (task.thumbnail != null) {
- task.thumbnail.setHasAlpha(false);
- mThumbnailCache.put(taskKey, task.thumbnail);
- }
- }
- if (task.thumbnail == null && tasksToLoadOut != null) {
- // Either the task has changed since the last active time, or it was not
- // previously cached, so try and load the task anew.
- tasksToLoadOut.add(task);
- }
- }
-
- // Add to the list of task keys
- if (taskKeysOut != null) {
- taskKeysOut.add(taskKey);
- }
- // Add the task to the stack
- tasksToAdd.add(task);
+ public void loadTasks(Context context, RecentsTaskLoadPlan plan,
+ RecentsTaskLoadPlan.Options opts) {
+ if (opts == null) {
+ throw new RuntimeException("Requires load options");
}
- stack.setTasks(tasksToAdd);
- stack.createAffiliatedGroupings(config);
- return stack;
+ plan.executePlan(opts, this);
+ if (opts.numVisibleTasks > 0) {
+ mNumVisibleTasksLoaded = opts.numVisibleTasks;
+ }
+
+ // Start the loader
+ mLoader.start(context);
}
/** Acquires the task resource data directly from the pool. */
@@ -591,24 +499,22 @@
case ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN:
// Stop the loader immediately when the UI is no longer visible
stopLoader();
- mThumbnailCache.trimToSize(Math.max(
- Constants.Values.RecentsTaskLoader.PreloadFirstTasksCount,
+ mThumbnailCache.trimToSize(Math.max(mNumVisibleTasksLoaded,
mMaxThumbnailCacheSize / 2));
- mApplicationIconCache.trimToSize(Math.max(
- Constants.Values.RecentsTaskLoader.PreloadFirstTasksCount,
+ mApplicationIconCache.trimToSize(Math.max(mNumVisibleTasksLoaded,
mMaxIconCacheSize / 2));
break;
case ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE:
case ComponentCallbacks2.TRIM_MEMORY_BACKGROUND:
// We are leaving recents, so trim the data a bit
- mThumbnailCache.trimToSize(mMaxThumbnailCacheSize / 2);
- mApplicationIconCache.trimToSize(mMaxIconCacheSize / 2);
+ mThumbnailCache.trimToSize(Math.max(1, mMaxThumbnailCacheSize / 2));
+ mApplicationIconCache.trimToSize(Math.max(1, mMaxIconCacheSize / 2));
break;
case ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW:
case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
// We are going to be low on memory
- mThumbnailCache.trimToSize(mMaxThumbnailCacheSize / 4);
- mApplicationIconCache.trimToSize(mMaxIconCacheSize / 4);
+ mThumbnailCache.trimToSize(Math.max(1, mMaxThumbnailCacheSize / 4));
+ mApplicationIconCache.trimToSize(Math.max(1, mMaxIconCacheSize / 4));
break;
case ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL:
case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
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 6093584..77a050a 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java
@@ -216,6 +216,9 @@
/** Requests all task stacks to start their exit-recents animation */
public void startExitToHomeAnimation(ViewAnimation.TaskViewExitContext ctx) {
+ // We have to increment/decrement the post animation trigger in case there are no children
+ // to ensure that it runs
+ ctx.postAnimationTrigger.increment();
int childCount = getChildCount();
for (int i = 0; i < childCount; i++) {
View child = getChildAt(i);
@@ -224,6 +227,7 @@
stackView.startExitToHomeAnimation(ctx);
}
}
+ ctx.postAnimationTrigger.decrement();
// Notify of the exit animation
mCb.onExitToHomeAnimationTriggered();
@@ -503,7 +507,7 @@
// Launch the app right away if there is no task view, otherwise, animate the icon out first
if (tv == null) {
- post(launchRunnable);
+ launchRunnable.run();
} else {
if (!task.group.isFrontMostTask(task)) {
// For affiliated tasks that are behind other tasks, we must animate the front cards
@@ -512,7 +516,7 @@
} else {
// Otherwise, we can start the task transition immediately
stackView.startLaunchTaskAnimation(tv, null, lockToTask);
- postDelayed(launchRunnable, 17);
+ launchRunnable.run();
}
}
}
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 bef4cd1..49fd792 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java
@@ -439,6 +439,8 @@
/** Updates the min and max virtual scroll bounds */
void updateMinMaxScroll(boolean boundScrollToNewMinMax, boolean launchedWithAltTab,
boolean launchedFromHome) {
+ if (mStack == null) return;
+
// Compute the min and max scroll values
mLayoutAlgorithm.computeMinMaxScroll(mStack.getTasks(), launchedWithAltTab, launchedFromHome);
@@ -563,6 +565,8 @@
@Override
public void onInitializeAccessibilityEvent(AccessibilityEvent event) {
super.onInitializeAccessibilityEvent(event);
+ if (mStack == null) return;
+
int childCount = getChildCount();
if (childCount > 0) {
TaskView backMostTask = (TaskView) getChildAt(0);
@@ -624,11 +628,24 @@
}
/**
+ * Computes the maximum number of visible tasks and thumbnails. Requires that
+ * updateMinMaxScrollForStack() is called first.
+ */
+ public TaskStackViewLayoutAlgorithm.VisibilityReport computeStackVisibilityReport() {
+ return mLayoutAlgorithm.computeStackVisibilityReport(mStack.getTasks());
+ }
+
+ /**
* This is called with the full window width and height to allow stack view children to
* perform the full screen transition down.
*/
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+ if (mStack == null) {
+ super.onMeasure(widthMeasureSpec, heightMeasureSpec);
+ return;
+ }
+
int width = MeasureSpec.getSize(widthMeasureSpec);
int height = MeasureSpec.getSize(heightMeasureSpec);
@@ -674,6 +691,11 @@
*/
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
+ if (mStack == null) {
+ super.onLayout(changed, left, top, right, bottom);
+ return;
+ }
+
// Layout each of the children
int childCount = getChildCount();
for (int i = 0; i < childCount; i++) {
@@ -831,7 +853,6 @@
/** Final callback after Recents is finally hidden. */
void onRecentsHidden() {
- reset();
setStack(null);
}
@@ -1006,6 +1027,8 @@
@Override
public void prepareViewToLeavePool(TaskView tv, Task task, boolean isNewView) {
+ if (mStack == null) return;
+
// It is possible for a view to be returned to the view pool before it is laid out,
// which means that we will need to relayout the view when it is first used next.
boolean requiresRelayout = tv.getWidth() <= 0 && !isNewView;
@@ -1144,6 +1167,8 @@
@Override
public void onPackagesChanged(RecentsPackageMonitor monitor, String packageName, int userId) {
+ if (mStack == null) return;
+
// Compute which components need to be removed
HashSet<ComponentName> removedComponents = monitor.computeComponentsRemoved(
mStack.getTaskKeys(), packageName, userId);
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewLayoutAlgorithm.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewLayoutAlgorithm.java
index c549d2b..5767e18 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewLayoutAlgorithm.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewLayoutAlgorithm.java
@@ -35,6 +35,18 @@
// These are all going to change
static final float StackPeekMinScale = 0.8f; // The min scale of the last card in the peek area
+ // A report of the visibility state of the stack
+ public class VisibilityReport {
+ public int numVisibleTasks;
+ public int numVisibleThumbnails;
+
+ /** Package level ctor */
+ VisibilityReport(int tasks, int thumbnails) {
+ numVisibleTasks = tasks;
+ numVisibleThumbnails = thumbnails;
+ }
+ }
+
RecentsConfiguration mConfig;
// The various rects that define the stack view
@@ -117,7 +129,8 @@
float pTaskHeightOffset = pAtBottomOfStackRect -
screenYToCurveProgress(mStackVisibleRect.bottom - taskHeight);
float pNavBarOffset = pAtBottomOfStackRect -
- screenYToCurveProgress(mStackVisibleRect.bottom - (mStackVisibleRect.bottom - mStackRect.bottom));
+ screenYToCurveProgress(mStackVisibleRect.bottom - (mStackVisibleRect.bottom -
+ mStackRect.bottom));
// Update the task offsets
float pAtBackMostCardTop = 0.5f;
@@ -130,8 +143,8 @@
if (i < (taskCount - 1)) {
// Increment the peek height
- float pPeek = task.group.isFrontMostTask(task) ? pBetweenAffiliateOffset :
- pWithinAffiliateOffset;
+ float pPeek = task.group.isFrontMostTask(task) ?
+ pBetweenAffiliateOffset : pWithinAffiliateOffset;
pAtSecondFrontMostCardTop = pAtFrontMostCardTop;
pAtFrontMostCardTop += pPeek;
}
@@ -153,19 +166,72 @@
mInitialScrollP = Math.max(0, mInitialScrollP);
}
+ /**
+ * Computes the maximum number of visible tasks and thumbnails. Requires that
+ * computeMinMaxScroll() is called first.
+ */
+ public VisibilityReport computeStackVisibilityReport(ArrayList<Task> tasks) {
+ if (tasks.size() <= 1) {
+ return new VisibilityReport(1, 1);
+ }
+
+ // Walk backwards in the task stack and count the number of tasks and visible thumbnails
+ int taskHeight = mTaskRect.height();
+ int numVisibleTasks = 1;
+ int numVisibleThumbnails = 1;
+ float progress = mTaskProgressMap.get(tasks.get(tasks.size() - 1).key) - mInitialScrollP;
+ int prevScreenY = curveProgressToScreenY(progress);
+ for (int i = tasks.size() - 2; i >= 0; i--) {
+ Task task = tasks.get(i);
+ progress = mTaskProgressMap.get(task.key) - mInitialScrollP;
+ if (progress < 0) {
+ break;
+ }
+ boolean isFrontMostTaskInGroup = task.group.isFrontMostTask(task);
+ if (isFrontMostTaskInGroup) {
+ float scaleAtP = curveProgressToScale(progress);
+ int scaleYOffsetAtP = (int) (((1f - scaleAtP) * taskHeight) / 2);
+ int screenY = curveProgressToScreenY(progress) + scaleYOffsetAtP;
+ boolean hasVisibleThumbnail = (prevScreenY - screenY) > mConfig.taskBarHeight;
+ if (hasVisibleThumbnail) {
+ numVisibleThumbnails++;
+ numVisibleTasks++;
+ prevScreenY = screenY;
+ } else {
+ // Once we hit the next front most task that does not have a visible thumbnail,
+ // walk through remaining visible set
+ for (int j = i; j >= 0; j--) {
+ numVisibleTasks++;
+ progress = mTaskProgressMap.get(tasks.get(j).key) - mInitialScrollP;
+ if (progress < 0) {
+ break;
+ }
+ }
+ break;
+ }
+ } else if (!isFrontMostTaskInGroup) {
+ // Affiliated task, no thumbnail
+ numVisibleTasks++;
+ }
+ }
+ return new VisibilityReport(numVisibleTasks, numVisibleThumbnails);
+ }
+
/** Update/get the transform */
- public TaskViewTransform getStackTransform(Task task, float stackScroll, TaskViewTransform transformOut,
- TaskViewTransform prevTransform) {
+ public TaskViewTransform getStackTransform(Task task, float stackScroll,
+ TaskViewTransform transformOut, TaskViewTransform prevTransform) {
// Return early if we have an invalid index
if (task == null || !mTaskProgressMap.containsKey(task.key)) {
transformOut.reset();
return transformOut;
}
- return getStackTransform(mTaskProgressMap.get(task.key), stackScroll, transformOut, prevTransform);
+ return getStackTransform(mTaskProgressMap.get(task.key), stackScroll, transformOut,
+ prevTransform);
}
/** Update/get the transform */
- public TaskViewTransform getStackTransform(float taskProgress, float stackScroll, TaskViewTransform transformOut, TaskViewTransform prevTransform) {
+ public TaskViewTransform getStackTransform(float taskProgress, float stackScroll,
+ TaskViewTransform transformOut, TaskViewTransform prevTransform) {
float pTaskRelative = taskProgress - stackScroll;
float pBounded = Math.max(0, Math.min(pTaskRelative, 1f));
// If the task top is outside of the bounds below the screen, then immediately reset it
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
index b531c681..9d7d310 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
@@ -523,7 +523,8 @@
case MotionEvent.ACTION_UP:
trackMovement(event);
if (mQsTracking) {
- flingQsWithCurrentVelocity();
+ flingQsWithCurrentVelocity(
+ event.getActionMasked() == MotionEvent.ACTION_CANCEL);
mQsTracking = false;
}
mIntercepting = false;
@@ -558,9 +559,9 @@
super.requestDisallowInterceptTouchEvent(disallowIntercept);
}
- private void flingQsWithCurrentVelocity() {
+ private void flingQsWithCurrentVelocity(boolean isCancelMotionEvent) {
float vel = getCurrentVelocity();
- flingSettings(vel, flingExpandsQs(vel));
+ flingSettings(vel, flingExpandsQs(vel) && !isCancelMotionEvent);
}
private boolean flingExpandsQs(float vel) {
@@ -729,7 +730,8 @@
float fraction = getQsExpansionFraction();
if ((fraction != 0f || y >= mInitialTouchY)
&& (fraction != 1f || y <= mInitialTouchY)) {
- flingQsWithCurrentVelocity();
+ flingQsWithCurrentVelocity(
+ event.getActionMasked() == MotionEvent.ACTION_CANCEL);
} else {
mScrollYOverride = -1;
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java
index c706ef0..47ce603 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java
@@ -330,7 +330,8 @@
vectorVel = (float) Math.hypot(
mVelocityTracker.getXVelocity(), mVelocityTracker.getYVelocity());
}
- boolean expand = flingExpands(vel, vectorVel);
+ boolean expand = flingExpands(vel, vectorVel)
+ || event.getActionMasked() == MotionEvent.ACTION_CANCEL;
onTrackingStopped(expand);
DozeLog.traceFling(expand, mTouchAboveFalsingThreshold,
mStatusBar.isFalsingThresholdNeeded(),
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
index ce2ce6b6..1697646 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -1309,6 +1309,8 @@
// not immersive & a full-screen alert should be shown
if (DEBUG) Log.d(TAG, "Notification has fullScreenIntent; sending fullScreenIntent");
try {
+ EventLog.writeEvent(EventLogTags.SYSUI_FULLSCREEN_NOTIFICATION,
+ notification.getKey());
notification.getNotification().fullScreenIntent.send();
} catch (PendingIntent.CanceledException e) {
}
@@ -1350,16 +1352,19 @@
@Override
public void scheduleHeadsUpOpen() {
+ mHandler.removeMessages(MSG_SHOW_HEADS_UP);
mHandler.sendEmptyMessage(MSG_SHOW_HEADS_UP);
}
@Override
public void scheduleHeadsUpClose() {
+ mHandler.removeMessages(MSG_HIDE_HEADS_UP);
mHandler.sendEmptyMessage(MSG_HIDE_HEADS_UP);
}
@Override
public void scheduleHeadsUpEscalation() {
+ mHandler.removeMessages(MSG_ESCALATE_HEADS_UP);
mHandler.sendEmptyMessage(MSG_ESCALATE_HEADS_UP);
}
@@ -2194,6 +2199,8 @@
if (DEBUG)
Log.d(TAG, "converting a heads up to fullScreen");
try {
+ EventLog.writeEvent(EventLogTags.SYSUI_HEADS_UP_ESCALATION,
+ sbn.getKey());
notification.fullScreenIntent.send();
} catch (PendingIntent.CanceledException e) {
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/Clock.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/Clock.java
index 55a0bba..537bfb9 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/Clock.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/Clock.java
@@ -149,7 +149,7 @@
final char MAGIC2 = '\uEF01';
SimpleDateFormat sdf;
- String format = is24 ? d.timeFormat24 : d.timeFormat12;
+ String format = is24 ? d.timeFormat_Hm : d.timeFormat_hm;
if (!format.equals(mClockFormatString)) {
/*
* Search for an unquoted "a" in the format string, so we can
diff --git a/packages/SystemUI/src/com/android/systemui/usb/StorageNotification.java b/packages/SystemUI/src/com/android/systemui/usb/StorageNotification.java
index dce5c37..f804736 100644
--- a/packages/SystemUI/src/com/android/systemui/usb/StorageNotification.java
+++ b/packages/SystemUI/src/com/android/systemui/usb/StorageNotification.java
@@ -28,6 +28,7 @@
import android.os.UserHandle;
import android.os.storage.StorageEventListener;
import android.os.storage.StorageManager;
+import android.os.storage.StorageVolume;
import android.provider.Settings;
import android.util.Log;
@@ -198,6 +199,8 @@
*/
Intent intent = new Intent();
intent.setClass(mContext, com.android.internal.app.ExternalMediaFormatActivity.class);
+ intent.putExtra(StorageVolume.EXTRA_STORAGE_VOLUME,
+ getVolumeByPath(mStorageManager.getVolumeList(), path));
PendingIntent pi = PendingIntent.getActivity(mContext, 0, intent, 0);
setMediaStorageNotification(
@@ -212,6 +215,8 @@
*/
Intent intent = new Intent();
intent.setClass(mContext, com.android.internal.app.ExternalMediaFormatActivity.class);
+ intent.putExtra(StorageVolume.EXTRA_STORAGE_VOLUME,
+ getVolumeByPath(mStorageManager.getVolumeList(), path));
PendingIntent pi = PendingIntent.getActivity(mContext, 0, intent, 0);
setMediaStorageNotification(
@@ -247,6 +252,19 @@
}
/**
+ * Get the corresponding StorageVolume object for a specific path.
+ */
+ private final StorageVolume getVolumeByPath(StorageVolume[] volumes, String path) {
+ for (StorageVolume volume : volumes) {
+ if (volume.getPath().equals(path)) {
+ return volume;
+ }
+ }
+ Log.w(TAG, "No storage found");
+ return null;
+ }
+
+ /**
* Update the state of the USB mass storage notification
*/
void updateUsbMassStorageNotification(boolean available) {
diff --git a/packages/VpnDialogs/res/values-eu-rES/strings.xml b/packages/VpnDialogs/res/values-eu-rES/strings.xml
index 7467195..b716509 100644
--- a/packages/VpnDialogs/res/values-eu-rES/strings.xml
+++ b/packages/VpnDialogs/res/values-eu-rES/strings.xml
@@ -17,7 +17,7 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="prompt" msgid="3183836924226407828">"Konektatzeko eskaera"</string>
- <string name="warning" msgid="809658604548412033">"<xliff:g id="APP">%s</xliff:g> VPN bidez konektatu nahi da sareko trafikoa kontrolatzeko. Iturburua fidagarria bada bakarrik baimendu. <br /> <br /> VPN konexioa aktibo dagoenean, <img src=vpn_icon /> agertuko da pantailaren goialdean."</string>
+ <string name="warning" msgid="809658604548412033">"<xliff:g id="APP">%s</xliff:g> aplikazioak VPN bidezko konexioa ezarri nahi du sareko trafikoa kontrolatzeko. Iturburua fidagarria bada bakarrik baimendu. <br /> <br /> VPN konexioa aktibo dagoenean, <img src=vpn_icon /> agertuko da pantailaren goialdean."</string>
<string name="legacy_title" msgid="192936250066580964">"VPN sarera konektatuta dago"</string>
<string name="configure" msgid="4905518375574791375">"Konfiguratu"</string>
<string name="disconnect" msgid="971412338304200056">"Deskonektatu"</string>
diff --git a/packages/VpnDialogs/res/values-my-rMM/strings.xml b/packages/VpnDialogs/res/values-my-rMM/strings.xml
index 6456c5e..b8a141c 100644
--- a/packages/VpnDialogs/res/values-my-rMM/strings.xml
+++ b/packages/VpnDialogs/res/values-my-rMM/strings.xml
@@ -17,11 +17,11 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="prompt" msgid="3183836924226407828">"ချိတ်ဆက်ရန် တောင်းဆိုချက်"</string>
- <string name="warning" msgid="809658604548412033">"<xliff:g id="APP">%s</xliff:g> က ကွန်ရက် လုပ်ငန်းကို စောင့်ကြည့်ခွင့် ပြုမည့် VPN ချိတ်ဆက်မှုကို ထူထောင်လိုသည်။ ရင်းမြစ်ကို သင်က ယုံကြည်မှသာ လက်ခံပါ။ <br /> <br /> <img src=vpn_icon /> မှာ VPN အလုပ်လုပ်နေလျှင် သင်၏ မျက်နှာပြင် ထိပ်မှာ ပေါ်လာမည်။"</string>
- <string name="legacy_title" msgid="192936250066580964">"VPNနှင့်ချိတ်ဆက်ထားသည်"</string>
+ <string name="warning" msgid="809658604548412033">"<xliff:g id="APP">%s</xliff:g> က ကွန်ရက် လုပ်ငန်းကို စောင့်ကြည့်ခွင့် ပြုမည့် VPN ချိတ်ဆက်မှုကို ထူထောင်လိုသည်။ ရင်းမြစ်ကို သင်က ယုံကြည်မှသာ လက်ခံပါ။ <br /> <br /> <img src=vpn_icon /> မှာ VPN အလုပ်လုပ်နေလျှင် သင်၏ မျက်နှာပြင် ထိပ်မှာ ပေါ်လာမည်။"</string>
+ <string name="legacy_title" msgid="192936250066580964">"VPNနှင့်ချိတ်ဆက်ထားသည်"</string>
<string name="configure" msgid="4905518375574791375">"ပုံပေါ်စေသည်"</string>
<string name="disconnect" msgid="971412338304200056">"ချိတ်ဆက်ခြင်းရပ်ရန်"</string>
- <string name="session" msgid="6470628549473641030">"သတ်မှတ်ပေးထားသည့်အချိန်:"</string>
+ <string name="session" msgid="6470628549473641030">"သတ်မှတ်ပေးထားသည့်အချိန်:"</string>
<string name="duration" msgid="3584782459928719435">"အချိန်ကာလ-"</string>
<string name="data_transmitted" msgid="7988167672982199061">"ပို့သည်-"</string>
<string name="data_received" msgid="4062776929376067820">"လက်ခံရရှိသည်"</string>
diff --git a/packages/WallpaperCropper/src/com/android/gallery3d/common/BitmapUtils.java b/packages/WallpaperCropper/src/com/android/gallery3d/common/BitmapUtils.java
index a671ed2..4e276db 100644
--- a/packages/WallpaperCropper/src/com/android/gallery3d/common/BitmapUtils.java
+++ b/packages/WallpaperCropper/src/com/android/gallery3d/common/BitmapUtils.java
@@ -23,7 +23,6 @@
import android.graphics.Matrix;
import android.graphics.Paint;
import android.os.Build;
-import android.util.FloatMath;
import android.util.Log;
import java.io.ByteArrayOutputStream;
@@ -72,7 +71,7 @@
&& minSideLength == UNCONSTRAINED) return 1;
int lowerBound = (maxNumOfPixels == UNCONSTRAINED) ? 1 :
- (int) FloatMath.ceil(FloatMath.sqrt((float) (w * h) / maxNumOfPixels));
+ (int) Math.ceil(Math.sqrt((double) (w * h) / maxNumOfPixels));
if (minSideLength == UNCONSTRAINED) {
return lowerBound;
@@ -96,7 +95,7 @@
// Find the min x that 1 / x >= scale
public static int computeSampleSizeLarger(float scale) {
- int initialSize = (int) FloatMath.floor(1f / scale);
+ int initialSize = (int) Math.floor(1 / scale);
if (initialSize <= 1) return 1;
return initialSize <= 8
@@ -107,7 +106,7 @@
// Find the max x that 1 / x <= scale.
public static int computeSampleSize(float scale) {
Utils.assertTrue(scale > 0);
- int initialSize = Math.max(1, (int) FloatMath.ceil(1 / scale));
+ int initialSize = Math.max(1, (int) Math.ceil(1 / scale));
return initialSize <= 8
? Utils.nextPowerOf2(initialSize)
: (initialSize + 7) / 8 * 8;
diff --git a/packages/WallpaperCropper/src/com/android/wallpapercropper/CropView.java b/packages/WallpaperCropper/src/com/android/wallpapercropper/CropView.java
index c3ef302..4405207 100644
--- a/packages/WallpaperCropper/src/com/android/wallpapercropper/CropView.java
+++ b/packages/WallpaperCropper/src/com/android/wallpapercropper/CropView.java
@@ -21,7 +21,6 @@
import android.graphics.Point;
import android.graphics.RectF;
import android.util.AttributeSet;
-import android.util.FloatMath;
import android.view.MotionEvent;
import android.view.ScaleGestureDetector;
import android.view.ScaleGestureDetector.OnScaleGestureListener;
@@ -300,12 +299,12 @@
adjustment[0] = (edges.right - getWidth()) / scale;
}
if (edges.top > 0) {
- adjustment[1] = FloatMath.ceil(edges.top / scale);
+ adjustment[1] = (float) Math.ceil(edges.top / scale);
} else if (edges.bottom < getHeight()) {
adjustment[1] = (edges.bottom - getHeight()) / scale;
}
for (int dim = 0; dim <= 1; dim++) {
- if (coef[dim] > 0) adjustment[dim] = FloatMath.ceil(adjustment[dim]);
+ if (coef[dim] > 0) adjustment[dim] = (float) Math.ceil(adjustment[dim]);
}
mInverseRotateMatrix.mapPoints(adjustment);
diff --git a/packages/services/Proxy/src/com/android/proxyhandler/ProxyService.java b/packages/services/Proxy/src/com/android/proxyhandler/ProxyService.java
index cbea188..970fdc7 100644
--- a/packages/services/Proxy/src/com/android/proxyhandler/ProxyService.java
+++ b/packages/services/Proxy/src/com/android/proxyhandler/ProxyService.java
@@ -33,8 +33,6 @@
/** Keep these values up-to-date with PacManager.java */
public static final String KEY_PROXY = "keyProxy";
public static final String HOST = "localhost";
- // STOPSHIP This being a static port means it can be hijacked by other apps.
- public static final int PORT = 8182;
public static final String EXCL_LIST = "";
@Override
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
index f29d5a6..1ead800 100644
--- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
@@ -525,6 +525,7 @@
private boolean mAllowTheaterModeWakeFromKey;
private boolean mAllowTheaterModeWakeFromPowerKey;
private boolean mAllowTheaterModeWakeFromMotion;
+ private boolean mAllowTheaterModeWakeFromMotionWhenNotDreaming;
private boolean mAllowTheaterModeWakeFromCameraLens;
private boolean mAllowTheaterModeWakeFromLidSwitch;
private boolean mAllowTheaterModeWakeFromWakeGesture;
@@ -1235,6 +1236,8 @@
com.android.internal.R.bool.config_allowTheaterModeWakeFromPowerKey);
mAllowTheaterModeWakeFromMotion = mContext.getResources().getBoolean(
com.android.internal.R.bool.config_allowTheaterModeWakeFromMotion);
+ mAllowTheaterModeWakeFromMotionWhenNotDreaming = mContext.getResources().getBoolean(
+ com.android.internal.R.bool.config_allowTheaterModeWakeFromMotionWhenNotDreaming);
mAllowTheaterModeWakeFromCameraLens = mContext.getResources().getBoolean(
com.android.internal.R.bool.config_allowTheaterModeWakeFromCameraLens);
mAllowTheaterModeWakeFromLidSwitch = mContext.getResources().getBoolean(
@@ -4129,7 +4132,7 @@
topIsFullscreen = (fl & WindowManager.LayoutParams.FLAG_FULLSCREEN) != 0
|| (mLastSystemUiFlags & View.SYSTEM_UI_FLAG_FULLSCREEN) != 0;
// The subtle difference between the window for mTopFullscreenOpaqueWindowState
- // and mTopIsFullscreen is that that mTopIsFullscreen is set only if the window
+ // and mTopIsFullscreen is that mTopIsFullscreen is set only if the window
// has the FLAG_FULLSCREEN set. Not sure if there is another way that to be the
// case though.
if (mStatusBarController.isTransientShowing()) {
@@ -4782,6 +4785,13 @@
return ACTION_PASS_TO_USER;
}
+ // If we have not passed the action up and we are in theater mode without dreaming,
+ // there will be no dream to intercept the touch and wake into ambient. The device should
+ // wake up in this case.
+ if (isTheaterModeEnabled() && (policyFlags & FLAG_WAKE) != 0) {
+ wakeUp(whenNanos / 1000000, mAllowTheaterModeWakeFromMotionWhenNotDreaming);
+ }
+
return 0;
}
diff --git a/policy/src/com/android/internal/policy/impl/WindowOrientationListener.java b/policy/src/com/android/internal/policy/impl/WindowOrientationListener.java
index 704da33..2f60d55 100644
--- a/policy/src/com/android/internal/policy/impl/WindowOrientationListener.java
+++ b/policy/src/com/android/internal/policy/impl/WindowOrientationListener.java
@@ -23,7 +23,6 @@
import android.hardware.SensorManager;
import android.os.Handler;
import android.os.SystemProperties;
-import android.util.FloatMath;
import android.util.Log;
import android.util.Slog;
import android.util.TimeUtils;
@@ -446,7 +445,7 @@
if (LOG) {
Slog.v(TAG, "Raw acceleration vector: "
+ "x=" + x + ", y=" + y + ", z=" + z
- + ", magnitude=" + FloatMath.sqrt(x * x + y * y + z * z));
+ + ", magnitude=" + Math.sqrt(x * x + y * y + z * z));
}
// Apply a low-pass filter to the acceleration up vector in cartesian space.
@@ -473,7 +472,7 @@
if (LOG) {
Slog.v(TAG, "Filtered acceleration vector: "
+ "x=" + x + ", y=" + y + ", z=" + z
- + ", magnitude=" + FloatMath.sqrt(x * x + y * y + z * z));
+ + ", magnitude=" + Math.sqrt(x * x + y * y + z * z));
}
skipSample = false;
}
@@ -487,7 +486,7 @@
boolean isSwinging = false;
if (!skipSample) {
// Calculate the magnitude of the acceleration vector.
- final float magnitude = FloatMath.sqrt(x * x + y * y + z * z);
+ final float magnitude = (float) Math.sqrt(x * x + y * y + z * z);
if (magnitude < NEAR_ZERO_MAGNITUDE) {
if (LOG) {
Slog.v(TAG, "Ignoring sensor data, magnitude too close to zero.");
diff --git a/rs/java/android/renderscript/RenderScript.java b/rs/java/android/renderscript/RenderScript.java
index 6c5c508..2ee4ff2 100644
--- a/rs/java/android/renderscript/RenderScript.java
+++ b/rs/java/android/renderscript/RenderScript.java
@@ -605,52 +605,14 @@
validate();
rsnScriptInvoke(mContext, id, slot);
}
- native void rsnScriptForEach(long con, long id, int slot, long ain, long aout, byte[] params);
- native void rsnScriptForEach(long con, long id, int slot, long ain, long aout);
- native void rsnScriptForEachClipped(long con, long id, int slot, long ain, long aout, byte[] params,
- int xstart, int xend, int ystart, int yend, int zstart, int zend);
- native void rsnScriptForEachClipped(long con, long id, int slot, long ain, long aout,
- int xstart, int xend, int ystart, int yend, int zstart, int zend);
- synchronized void nScriptForEach(long id, int slot, long ain, long aout, byte[] params) {
+
+ native void rsnScriptForEach(long con, long id, int slot, long[] ains,
+ long aout, byte[] params, int[] limits);
+
+ synchronized void nScriptForEach(long id, int slot, long[] ains, long aout,
+ byte[] params, int[] limits) {
validate();
- if (params == null) {
- rsnScriptForEach(mContext, id, slot, ain, aout);
- } else {
- rsnScriptForEach(mContext, id, slot, ain, aout, params);
- }
- }
-
- synchronized void nScriptForEachClipped(long id, int slot, long ain, long aout, byte[] params,
- int xstart, int xend, int ystart, int yend, int zstart, int zend) {
- validate();
- if (params == null) {
- rsnScriptForEachClipped(mContext, id, slot, ain, aout, xstart, xend, ystart, yend, zstart, zend);
- } else {
- rsnScriptForEachClipped(mContext, id, slot, ain, aout, params, xstart, xend, ystart, yend, zstart, zend);
- }
- }
-
- /**
- * Multi-input code.
- *
- */
-
- // @hide
- native void rsnScriptForEachMultiClipped(long con, long id, int slot, long[] ains, long aout, byte[] params,
- int xstart, int xend, int ystart, int yend, int zstart, int zend);
- // @hide
- native void rsnScriptForEachMultiClipped(long con, long id, int slot, long[] ains, long aout,
- int xstart, int xend, int ystart, int yend, int zstart, int zend);
-
- // @hide
- synchronized void nScriptForEachMultiClipped(long id, int slot, long[] ains, long aout, byte[] params,
- int xstart, int xend, int ystart, int yend, int zstart, int zend) {
- validate();
- if (params == null) {
- rsnScriptForEachMultiClipped(mContext, id, slot, ains, aout, xstart, xend, ystart, yend, zstart, zend);
- } else {
- rsnScriptForEachMultiClipped(mContext, id, slot, ains, aout, params, xstart, xend, ystart, yend, zstart, zend);
- }
+ rsnScriptForEach(mContext, id, slot, ains, aout, params, limits);
}
native void rsnScriptInvokeV(long con, long id, int slot, byte[] params);
diff --git a/rs/java/android/renderscript/Script.java b/rs/java/android/renderscript/Script.java
index c49ef94..eb1687a 100644
--- a/rs/java/android/renderscript/Script.java
+++ b/rs/java/android/renderscript/Script.java
@@ -48,7 +48,8 @@
/**
* Only to be used by generated reflected classes.
*/
- protected KernelID createKernelID(int slot, int sig, Element ein, Element eout) {
+ protected KernelID createKernelID(int slot, int sig, Element ein,
+ Element eout) {
KernelID k = mKIDs.get(slot);
if (k != null) {
return k;
@@ -127,59 +128,56 @@
* Only intended for use by generated reflected code.
*
*/
- protected void forEach(int slot, Allocation ain, Allocation aout, FieldPacker v) {
- mRS.validate();
- mRS.validateObject(ain);
- mRS.validateObject(aout);
- if (ain == null && aout == null) {
- throw new RSIllegalArgumentException(
- "At least one of ain or aout is required to be non-null.");
- }
- long in_id = 0;
- if (ain != null) {
- in_id = ain.getID(mRS);
- }
- long out_id = 0;
- if (aout != null) {
- out_id = aout.getID(mRS);
- }
- byte[] params = null;
- if (v != null) {
- params = v.getData();
- }
- mRS.nScriptForEach(getID(mRS), slot, in_id, out_id, params);
+ protected void forEach(int slot, Allocation ain, Allocation aout,
+ FieldPacker v) {
+ forEach(slot, ain, aout, v, null);
}
/**
* Only intended for use by generated reflected code.
*
*/
- protected void forEach(int slot, Allocation ain, Allocation aout, FieldPacker v, LaunchOptions sc) {
+ protected void forEach(int slot, Allocation ain, Allocation aout,
+ FieldPacker v, LaunchOptions sc) {
+ // TODO: Is this necessary if nScriptForEach calls validate as well?
mRS.validate();
mRS.validateObject(ain);
mRS.validateObject(aout);
+
if (ain == null && aout == null) {
throw new RSIllegalArgumentException(
"At least one of ain or aout is required to be non-null.");
}
- if (sc == null) {
- forEach(slot, ain, aout, v);
- return;
- }
- long in_id = 0;
+ long[] in_ids = null;
if (ain != null) {
- in_id = ain.getID(mRS);
+ in_ids = mInIdsBuffer;
+ in_ids[0] = ain.getID(mRS);
}
+
long out_id = 0;
if (aout != null) {
out_id = aout.getID(mRS);
}
+
byte[] params = null;
if (v != null) {
params = v.getData();
}
- mRS.nScriptForEachClipped(getID(mRS), slot, in_id, out_id, params, sc.xstart, sc.xend, sc.ystart, sc.yend, sc.zstart, sc.zend);
+
+ int[] limits = null;
+ if (sc != null) {
+ limits = new int[6];
+
+ limits[0] = sc.xstart;
+ limits[1] = sc.xend;
+ limits[2] = sc.ystart;
+ limits[3] = sc.yend;
+ limits[4] = sc.zstart;
+ limits[5] = sc.zend;
+ }
+
+ mRS.nScriptForEach(getID(mRS), slot, in_ids, out_id, params, limits);
}
/**
@@ -187,8 +185,9 @@
*
* @hide
*/
- protected void forEach(int slot, Allocation[] ains, Allocation aout, FieldPacker v) {
- forEach(slot, ains, aout, v, new LaunchOptions());
+ protected void forEach(int slot, Allocation[] ains, Allocation aout,
+ FieldPacker v) {
+ forEach(slot, ains, aout, v, null);
}
/**
@@ -196,24 +195,20 @@
*
* @hide
*/
- protected void forEach(int slot, Allocation[] ains, Allocation aout, FieldPacker v, LaunchOptions sc) {
+ protected void forEach(int slot, Allocation[] ains, Allocation aout,
+ FieldPacker v, LaunchOptions sc) {
+ // TODO: Is this necessary if nScriptForEach calls validate as well?
mRS.validate();
-
for (Allocation ain : ains) {
mRS.validateObject(ain);
}
-
mRS.validateObject(aout);
+
if (ains == null && aout == null) {
throw new RSIllegalArgumentException(
"At least one of ain or aout is required to be non-null.");
}
- if (sc == null) {
- forEach(slot, ains, aout, v);
- return;
- }
-
long[] in_ids = new long[ains.length];
for (int index = 0; index < ains.length; ++index) {
in_ids[index] = ains[index].getID(mRS);
@@ -223,15 +218,33 @@
if (aout != null) {
out_id = aout.getID(mRS);
}
+
byte[] params = null;
if (v != null) {
params = v.getData();
}
- mRS.nScriptForEachMultiClipped(getID(mRS), slot, in_ids, out_id, params, sc.xstart, sc.xend, sc.ystart, sc.yend, sc.zstart, sc.zend);
+
+ int[] limits = null;
+ if (sc != null) {
+ limits = new int[6];
+
+ limits[0] = sc.xstart;
+ limits[1] = sc.xend;
+ limits[2] = sc.ystart;
+ limits[3] = sc.yend;
+ limits[4] = sc.zstart;
+ limits[5] = sc.zend;
+ }
+
+ mRS.nScriptForEach(getID(mRS), slot, in_ids, out_id, params, limits);
}
+ long[] mInIdsBuffer;
+
Script(long id, RenderScript rs) {
super(id, rs);
+
+ mInIdsBuffer = new long[1];
}
@@ -243,11 +256,17 @@
mRS.validate();
mRS.validateObject(va);
if (va != null) {
- if (mRS.getApplicationContext().getApplicationInfo().targetSdkVersion >= 20) {
+
+ android.content.Context context = mRS.getApplicationContext();
+
+ if (context.getApplicationInfo().targetSdkVersion >= 20) {
final Type t = va.mType;
- if (t.hasMipmaps() || t.hasFaces() || (t.getY() != 0) || (t.getZ() != 0)) {
+ if (t.hasMipmaps() || t.hasFaces() || (t.getY() != 0) ||
+ (t.getZ() != 0)) {
+
throw new RSIllegalArgumentException(
- "API 20+ only allows simple 1D allocations to be used with bind.");
+ "API 20+ only allows simple 1D allocations to be " +
+ "used with bind.");
}
}
mRS.nScriptBindAllocation(getID(mRS), va.getID(mRS), slot);
@@ -378,11 +397,14 @@
protected Allocation mAllocation;
protected void init(RenderScript rs, int dimx) {
- mAllocation = Allocation.createSized(rs, mElement, dimx, Allocation.USAGE_SCRIPT);
+ mAllocation = Allocation.createSized(rs, mElement, dimx,
+ Allocation.USAGE_SCRIPT);
}
protected void init(RenderScript rs, int dimx, int usages) {
- mAllocation = Allocation.createSized(rs, mElement, dimx, Allocation.USAGE_SCRIPT | usages);
+ mAllocation =
+ Allocation.createSized(rs, mElement, dimx,
+ Allocation.USAGE_SCRIPT | usages);
}
protected FieldBase() {
diff --git a/rs/jni/Android.mk b/rs/jni/Android.mk
index f1ddc07..f1f0bfc 100644
--- a/rs/jni/Android.mk
+++ b/rs/jni/Android.mk
@@ -5,27 +5,28 @@
android_renderscript_RenderScript.cpp
LOCAL_SHARED_LIBRARIES := \
- libandroid_runtime \
- libandroidfw \
- libnativehelper \
- libRS \
- libcutils \
- liblog \
- libskia \
- libutils \
- libui \
- libgui
+ libandroid_runtime \
+ libandroidfw \
+ libnativehelper \
+ libRS \
+ libcutils \
+ liblog \
+ libskia \
+ libutils \
+ libui \
+ libgui
LOCAL_STATIC_LIBRARIES :=
rs_generated_include_dir := $(call intermediates-dir-for,SHARED_LIBRARIES,libRS,,)
LOCAL_C_INCLUDES += \
- $(JNI_H_INCLUDE) \
- frameworks/rs \
- $(rs_generated_include_dir)
+ $(JNI_H_INCLUDE) \
+ frameworks/rs \
+ $(rs_generated_include_dir)
-LOCAL_CFLAGS += -Wno-unused-parameter
+LOCAL_CFLAGS += -Wno-unused-parameter -std=c++11
+LOCAL_CFLAGS += -Wall -Werror -Wunused -Wunreachable-code
LOCAL_ADDITIONAL_DEPENDENCIES := $(addprefix $(rs_generated_include_dir)/,rsgApiFuncDecl.h)
LOCAL_MODULE:= librs_jni
diff --git a/rs/jni/android_renderscript_RenderScript.cpp b/rs/jni/android_renderscript_RenderScript.cpp
index 13a649a..ff37150 100644
--- a/rs/jni/android_renderscript_RenderScript.cpp
+++ b/rs/jni/android_renderscript_RenderScript.cpp
@@ -43,13 +43,16 @@
#include <android_runtime/android_graphics_SurfaceTexture.h>
//#define LOG_API ALOGE
-#define LOG_API(...)
+static constexpr bool kLogApi = false;
using namespace android;
+template <typename... T>
+void UNUSED(T... t) {}
+
#define PER_ARRAY_TYPE(flag, fnc, readonly, ...) { \
jint len = 0; \
- void *ptr = NULL; \
+ void *ptr = nullptr; \
size_t typeBytes = 0; \
jint relFlag = 0; \
if (readonly) { \
@@ -106,13 +109,14 @@
default: \
break; \
} \
+ UNUSED(len, ptr, typeBytes, relFlag); \
}
class AutoJavaStringToUTF8 {
public:
AutoJavaStringToUTF8(JNIEnv* env, jstring str) : fEnv(env), fJStr(str) {
- fCStr = env->GetStringUTFChars(str, NULL);
+ fCStr = env->GetStringUTFChars(str, nullptr);
fLength = env->GetStringUTFLength(str);
}
~AutoJavaStringToUTF8() {
@@ -132,14 +136,14 @@
public:
AutoJavaStringArrayToUTF8(JNIEnv* env, jobjectArray strings, jsize stringsLength)
: mEnv(env), mStrings(strings), mStringsLength(stringsLength) {
- mCStrings = NULL;
- mSizeArray = NULL;
+ mCStrings = nullptr;
+ mSizeArray = nullptr;
if (stringsLength > 0) {
mCStrings = (const char **)calloc(stringsLength, sizeof(char *));
mSizeArray = (size_t*)calloc(stringsLength, sizeof(size_t));
for (jsize ct = 0; ct < stringsLength; ct ++) {
jstring s = (jstring)mEnv->GetObjectArrayElement(mStrings, ct);
- mCStrings[ct] = mEnv->GetStringUTFChars(s, NULL);
+ mCStrings[ct] = mEnv->GetStringUTFChars(s, nullptr);
mSizeArray[ct] = mEnv->GetStringUTFLength(s);
}
}
@@ -168,7 +172,6 @@
static jfieldID gContextId = 0;
static jfieldID gNativeBitmapID = 0;
-static jfieldID gTypeNativeCache = 0;
static void _nInit(JNIEnv *_env, jclass _this)
{
@@ -183,14 +186,18 @@
static void
nContextFinish(JNIEnv *_env, jobject _this, jlong con)
{
- LOG_API("nContextFinish, con(%p)", (RsContext)con);
+ if (kLogApi) {
+ ALOGD("nContextFinish, con(%p)", (RsContext)con);
+ }
rsContextFinish((RsContext)con);
}
static void
nAssignName(JNIEnv *_env, jobject _this, jlong con, jlong obj, jbyteArray str)
{
- LOG_API("nAssignName, con(%p), obj(%p)", (RsContext)con, (void *)obj);
+ if (kLogApi) {
+ ALOGD("nAssignName, con(%p), obj(%p)", (RsContext)con, (void *)obj);
+ }
jint len = _env->GetArrayLength(str);
jbyte * cptr = (jbyte *) _env->GetPrimitiveArrayCritical(str, 0);
rsAssignName((RsContext)con, (void *)obj, (const char *)cptr, len);
@@ -200,11 +207,13 @@
static jstring
nGetName(JNIEnv *_env, jobject _this, jlong con, jlong obj)
{
- LOG_API("nGetName, con(%p), obj(%p)", (RsContext)con, (void *)obj);
- const char *name = NULL;
+ if (kLogApi) {
+ ALOGD("nGetName, con(%p), obj(%p)", (RsContext)con, (void *)obj);
+ }
+ const char *name = nullptr;
rsaGetName((RsContext)con, (void *)obj, &name);
- if(name == NULL || strlen(name) == 0) {
- return NULL;
+ if(name == nullptr || strlen(name) == 0) {
+ return nullptr;
}
return _env->NewStringUTF(name);
}
@@ -212,7 +221,9 @@
static void
nObjDestroy(JNIEnv *_env, jobject _this, jlong con, jlong obj)
{
- LOG_API("nObjDestroy, con(%p) obj(%p)", (RsContext)con, (void *)obj);
+ if (kLogApi) {
+ ALOGD("nObjDestroy, con(%p) obj(%p)", (RsContext)con, (void *)obj);
+ }
rsObjDestroy((RsContext)con, (void *)obj);
}
@@ -221,28 +232,36 @@
static jlong
nDeviceCreate(JNIEnv *_env, jobject _this)
{
- LOG_API("nDeviceCreate");
+ if (kLogApi) {
+ ALOGD("nDeviceCreate");
+ }
return (jlong)(uintptr_t)rsDeviceCreate();
}
static void
nDeviceDestroy(JNIEnv *_env, jobject _this, jlong dev)
{
- LOG_API("nDeviceDestroy");
+ if (kLogApi) {
+ ALOGD("nDeviceDestroy");
+ }
return rsDeviceDestroy((RsDevice)dev);
}
static void
nDeviceSetConfig(JNIEnv *_env, jobject _this, jlong dev, jint p, jint value)
{
- LOG_API("nDeviceSetConfig dev(%p), param(%i), value(%i)", (void *)dev, p, value);
+ if (kLogApi) {
+ ALOGD("nDeviceSetConfig dev(%p), param(%i), value(%i)", (void *)dev, p, value);
+ }
return rsDeviceSetConfig((RsDevice)dev, (RsDeviceParam)p, value);
}
static jlong
nContextCreate(JNIEnv *_env, jobject _this, jlong dev, jint ver, jint sdkVer, jint ct)
{
- LOG_API("nContextCreate");
+ if (kLogApi) {
+ ALOGD("nContextCreate");
+ }
return (jlong)(uintptr_t)rsContextCreate((RsDevice)dev, ver, sdkVer, (RsContextType)ct, 0);
}
@@ -266,14 +285,18 @@
sc.samplesPref = samplesPref;
sc.samplesQ = samplesQ;
- LOG_API("nContextCreateGL");
+ if (kLogApi) {
+ ALOGD("nContextCreateGL");
+ }
return (jlong)(uintptr_t)rsContextCreateGL((RsDevice)dev, ver, sdkVer, sc, dpi);
}
static void
nContextSetPriority(JNIEnv *_env, jobject _this, jlong con, jint p)
{
- LOG_API("ContextSetPriority, con(%p), priority(%i)", (RsContext)con, p);
+ if (kLogApi) {
+ ALOGD("ContextSetPriority, con(%p), priority(%i)", (RsContext)con, p);
+ }
rsContextSetPriority((RsContext)con, p);
}
@@ -282,10 +305,13 @@
static void
nContextSetSurface(JNIEnv *_env, jobject _this, jlong con, jint width, jint height, jobject wnd)
{
- LOG_API("nContextSetSurface, con(%p), width(%i), height(%i), surface(%p)", (RsContext)con, width, height, (Surface *)wnd);
+ if (kLogApi) {
+ ALOGD("nContextSetSurface, con(%p), width(%i), height(%i), surface(%p)", (RsContext)con,
+ width, height, (Surface *)wnd);
+ }
- ANativeWindow * window = NULL;
- if (wnd == NULL) {
+ ANativeWindow * window = nullptr;
+ if (wnd == nullptr) {
} else {
window = android_view_Surface_getNativeWindow(_env, wnd).get();
@@ -297,28 +323,36 @@
static void
nContextDestroy(JNIEnv *_env, jobject _this, jlong con)
{
- LOG_API("nContextDestroy, con(%p)", (RsContext)con);
+ if (kLogApi) {
+ ALOGD("nContextDestroy, con(%p)", (RsContext)con);
+ }
rsContextDestroy((RsContext)con);
}
static void
nContextDump(JNIEnv *_env, jobject _this, jlong con, jint bits)
{
- LOG_API("nContextDump, con(%p) bits(%i)", (RsContext)con, bits);
+ if (kLogApi) {
+ ALOGD("nContextDump, con(%p) bits(%i)", (RsContext)con, bits);
+ }
rsContextDump((RsContext)con, bits);
}
static void
nContextPause(JNIEnv *_env, jobject _this, jlong con)
{
- LOG_API("nContextPause, con(%p)", (RsContext)con);
+ if (kLogApi) {
+ ALOGD("nContextPause, con(%p)", (RsContext)con);
+ }
rsContextPause((RsContext)con);
}
static void
nContextResume(JNIEnv *_env, jobject _this, jlong con)
{
- LOG_API("nContextResume, con(%p)", (RsContext)con);
+ if (kLogApi) {
+ ALOGD("nContextResume, con(%p)", (RsContext)con);
+ }
rsContextResume((RsContext)con);
}
@@ -326,7 +360,9 @@
static jstring
nContextGetErrorMessage(JNIEnv *_env, jobject _this, jlong con)
{
- LOG_API("nContextGetErrorMessage, con(%p)", (RsContext)con);
+ if (kLogApi) {
+ ALOGD("nContextGetErrorMessage, con(%p)", (RsContext)con);
+ }
char buf[1024];
size_t receiveLen;
@@ -345,8 +381,10 @@
nContextGetUserMessage(JNIEnv *_env, jobject _this, jlong con, jintArray data)
{
jint len = _env->GetArrayLength(data);
- LOG_API("nContextGetMessage, con(%p), len(%i)", (RsContext)con, len);
- jint *ptr = _env->GetIntArrayElements(data, NULL);
+ if (kLogApi) {
+ ALOGD("nContextGetMessage, con(%p), len(%i)", (RsContext)con, len);
+ }
+ jint *ptr = _env->GetIntArrayElements(data, nullptr);
size_t receiveLen;
uint32_t subID;
int id = rsContextGetMessage((RsContext)con,
@@ -363,8 +401,10 @@
static jint
nContextPeekMessage(JNIEnv *_env, jobject _this, jlong con, jintArray auxData)
{
- LOG_API("nContextPeekMessage, con(%p)", (RsContext)con);
- jint *auxDataPtr = _env->GetIntArrayElements(auxData, NULL);
+ if (kLogApi) {
+ ALOGD("nContextPeekMessage, con(%p)", (RsContext)con);
+ }
+ jint *auxDataPtr = _env->GetIntArrayElements(auxData, nullptr);
size_t receiveLen;
uint32_t subID;
int id = rsContextPeekMessage((RsContext)con, &receiveLen, sizeof(receiveLen),
@@ -377,26 +417,32 @@
static void nContextInitToClient(JNIEnv *_env, jobject _this, jlong con)
{
- LOG_API("nContextInitToClient, con(%p)", (RsContext)con);
+ if (kLogApi) {
+ ALOGD("nContextInitToClient, con(%p)", (RsContext)con);
+ }
rsContextInitToClient((RsContext)con);
}
static void nContextDeinitToClient(JNIEnv *_env, jobject _this, jlong con)
{
- LOG_API("nContextDeinitToClient, con(%p)", (RsContext)con);
+ if (kLogApi) {
+ ALOGD("nContextDeinitToClient, con(%p)", (RsContext)con);
+ }
rsContextDeinitToClient((RsContext)con);
}
static void
nContextSendMessage(JNIEnv *_env, jobject _this, jlong con, jint id, jintArray data)
{
- jint *ptr = NULL;
+ jint *ptr = nullptr;
jint len = 0;
if (data) {
len = _env->GetArrayLength(data);
- ptr = _env->GetIntArrayElements(data, NULL);
+ ptr = _env->GetIntArrayElements(data, nullptr);
}
- LOG_API("nContextSendMessage, con(%p), id(%i), len(%i)", (RsContext)con, id, len);
+ if (kLogApi) {
+ ALOGD("nContextSendMessage, con(%p), id(%i), len(%i)", (RsContext)con, id, len);
+ }
rsContextSendMessage((RsContext)con, id, (const uint8_t *)ptr, len * sizeof(int));
if (data) {
_env->ReleaseIntArrayElements(data, ptr, JNI_ABORT);
@@ -406,10 +452,15 @@
static jlong
-nElementCreate(JNIEnv *_env, jobject _this, jlong con, jlong type, jint kind, jboolean norm, jint size)
+nElementCreate(JNIEnv *_env, jobject _this, jlong con, jlong type, jint kind, jboolean norm,
+ jint size)
{
- LOG_API("nElementCreate, con(%p), type(%i), kind(%i), norm(%i), size(%i)", (RsContext)con, type, kind, norm, size);
- return (jlong)(uintptr_t)rsElementCreate((RsContext)con, (RsDataType)type, (RsDataKind)kind, norm, size);
+ if (kLogApi) {
+ ALOGD("nElementCreate, con(%p), type(%i), kind(%i), norm(%i), size(%i)", (RsContext)con,
+ type, kind, norm, size);
+ }
+ return (jlong)(uintptr_t)rsElementCreate((RsContext)con, (RsDataType)type, (RsDataKind)kind,
+ norm, size);
}
static jlong
@@ -417,10 +468,12 @@
jlongArray _ids, jobjectArray _names, jintArray _arraySizes)
{
int fieldCount = _env->GetArrayLength(_ids);
- LOG_API("nElementCreate2, con(%p)", (RsContext)con);
+ if (kLogApi) {
+ ALOGD("nElementCreate2, con(%p)", (RsContext)con);
+ }
- jlong *jIds = _env->GetLongArrayElements(_ids, NULL);
- jint *jArraySizes = _env->GetIntArrayElements(_arraySizes, NULL);
+ jlong *jIds = _env->GetLongArrayElements(_ids, nullptr);
+ jint *jArraySizes = _env->GetIntArrayElements(_arraySizes, nullptr);
RsElement *ids = (RsElement*)malloc(fieldCount * sizeof(RsElement));
uint32_t *arraySizes = (uint32_t *)malloc(fieldCount * sizeof(uint32_t));
@@ -452,7 +505,9 @@
nElementGetNativeData(JNIEnv *_env, jobject _this, jlong con, jlong id, jintArray _elementData)
{
int dataSize = _env->GetArrayLength(_elementData);
- LOG_API("nElementGetNativeData, con(%p)", (RsContext)con);
+ if (kLogApi) {
+ ALOGD("nElementGetNativeData, con(%p)", (RsContext)con);
+ }
// we will pack mType; mKind; mNormalized; mVectorSize; NumSubElements
assert(dataSize == 5);
@@ -474,13 +529,16 @@
jintArray _arraySizes)
{
uint32_t dataSize = _env->GetArrayLength(_IDs);
- LOG_API("nElementGetSubElements, con(%p)", (RsContext)con);
+ if (kLogApi) {
+ ALOGD("nElementGetSubElements, con(%p)", (RsContext)con);
+ }
uintptr_t *ids = (uintptr_t*)malloc(dataSize * sizeof(uintptr_t));
const char **names = (const char **)malloc(dataSize * sizeof(const char *));
uint32_t *arraySizes = (uint32_t *)malloc(dataSize * sizeof(uint32_t));
- rsaElementGetSubElements((RsContext)con, (RsElement)id, ids, names, arraySizes, (uint32_t)dataSize);
+ rsaElementGetSubElements((RsContext)con, (RsElement)id, ids, names, arraySizes,
+ (uint32_t)dataSize);
for(uint32_t i = 0; i < dataSize; i++) {
const jlong id = (jlong)(uintptr_t)ids[i];
@@ -501,10 +559,13 @@
nTypeCreate(JNIEnv *_env, jobject _this, jlong con, jlong eid,
jint dimx, jint dimy, jint dimz, jboolean mips, jboolean faces, jint yuv)
{
- LOG_API("nTypeCreate, con(%p) eid(%p), x(%i), y(%i), z(%i), mips(%i), faces(%i), yuv(%i)",
- (RsContext)con, eid, dimx, dimy, dimz, mips, faces, yuv);
+ if (kLogApi) {
+ ALOGD("nTypeCreate, con(%p) eid(%p), x(%i), y(%i), z(%i), mips(%i), faces(%i), yuv(%i)",
+ (RsContext)con, eid, dimx, dimy, dimz, mips, faces, yuv);
+ }
- return (jlong)(uintptr_t)rsTypeCreate((RsContext)con, (RsElement)eid, dimx, dimy, dimz, mips, faces, yuv);
+ return (jlong)(uintptr_t)rsTypeCreate((RsContext)con, (RsElement)eid, dimx, dimy, dimz, mips,
+ faces, yuv);
}
static void
@@ -515,7 +576,9 @@
int elementCount = _env->GetArrayLength(_typeData);
assert(elementCount == 6);
- LOG_API("nTypeGetNativeData, con(%p)", (RsContext)con);
+ if (kLogApi) {
+ ALOGD("nTypeGetNativeData, con(%p)", (RsContext)con);
+ }
uintptr_t typeData[6];
rsaTypeGetNativeData((RsContext)con, (RsType)id, typeData, 6);
@@ -529,27 +592,39 @@
// -----------------------------------
static jlong
-nAllocationCreateTyped(JNIEnv *_env, jobject _this, jlong con, jlong type, jint mips, jint usage, jlong pointer)
+nAllocationCreateTyped(JNIEnv *_env, jobject _this, jlong con, jlong type, jint mips, jint usage,
+ jlong pointer)
{
- LOG_API("nAllocationCreateTyped, con(%p), type(%p), mip(%i), usage(%i), ptr(%p)", (RsContext)con, (RsElement)type, mips, usage, (void *)pointer);
- return (jlong)(uintptr_t) rsAllocationCreateTyped((RsContext)con, (RsType)type, (RsAllocationMipmapControl)mips, (uint32_t)usage, (uintptr_t)pointer);
+ if (kLogApi) {
+ ALOGD("nAllocationCreateTyped, con(%p), type(%p), mip(%i), usage(%i), ptr(%p)",
+ (RsContext)con, (RsElement)type, mips, usage, (void *)pointer);
+ }
+ return (jlong)(uintptr_t) rsAllocationCreateTyped((RsContext)con, (RsType)type,
+ (RsAllocationMipmapControl)mips,
+ (uint32_t)usage, (uintptr_t)pointer);
}
static void
nAllocationSyncAll(JNIEnv *_env, jobject _this, jlong con, jlong a, jint bits)
{
- LOG_API("nAllocationSyncAll, con(%p), a(%p), bits(0x%08x)", (RsContext)con, (RsAllocation)a, bits);
+ if (kLogApi) {
+ ALOGD("nAllocationSyncAll, con(%p), a(%p), bits(0x%08x)", (RsContext)con, (RsAllocation)a,
+ bits);
+ }
rsAllocationSyncAll((RsContext)con, (RsAllocation)a, (RsAllocationUsageType)bits);
}
static jobject
nAllocationGetSurface(JNIEnv *_env, jobject _this, jlong con, jlong a)
{
- LOG_API("nAllocationGetSurface, con(%p), a(%p)", (RsContext)con, (RsAllocation)a);
+ if (kLogApi) {
+ ALOGD("nAllocationGetSurface, con(%p), a(%p)", (RsContext)con, (RsAllocation)a);
+ }
- IGraphicBufferProducer *v = (IGraphicBufferProducer *)rsAllocationGetSurface((RsContext)con, (RsAllocation)a);
+ IGraphicBufferProducer *v = (IGraphicBufferProducer *)rsAllocationGetSurface((RsContext)con,
+ (RsAllocation)a);
sp<IGraphicBufferProducer> bp = v;
- v->decStrong(NULL);
+ v->decStrong(nullptr);
jobject o = android_view_Surface_createFromIGraphicBufferProducer(_env, bp);
return o;
@@ -558,28 +633,35 @@
static void
nAllocationSetSurface(JNIEnv *_env, jobject _this, jlong con, jlong alloc, jobject sur)
{
- LOG_API("nAllocationSetSurface, con(%p), alloc(%p), surface(%p)",
- (RsContext)con, (RsAllocation)alloc, (Surface *)sur);
+ if (kLogApi) {
+ ALOGD("nAllocationSetSurface, con(%p), alloc(%p), surface(%p)", (RsContext)con,
+ (RsAllocation)alloc, (Surface *)sur);
+ }
sp<Surface> s;
if (sur != 0) {
s = android_view_Surface_getSurface(_env, sur);
}
- rsAllocationSetSurface((RsContext)con, (RsAllocation)alloc, static_cast<ANativeWindow *>(s.get()));
+ rsAllocationSetSurface((RsContext)con, (RsAllocation)alloc,
+ static_cast<ANativeWindow *>(s.get()));
}
static void
nAllocationIoSend(JNIEnv *_env, jobject _this, jlong con, jlong alloc)
{
- LOG_API("nAllocationIoSend, con(%p), alloc(%p)", (RsContext)con, alloc);
+ if (kLogApi) {
+ ALOGD("nAllocationIoSend, con(%p), alloc(%p)", (RsContext)con, alloc);
+ }
rsAllocationIoSend((RsContext)con, (RsAllocation)alloc);
}
static void
nAllocationIoReceive(JNIEnv *_env, jobject _this, jlong con, jlong alloc)
{
- LOG_API("nAllocationIoReceive, con(%p), alloc(%p)", (RsContext)con, alloc);
+ if (kLogApi) {
+ ALOGD("nAllocationIoReceive, con(%p), alloc(%p)", (RsContext)con, alloc);
+ }
rsAllocationIoReceive((RsContext)con, (RsAllocation)alloc);
}
@@ -587,12 +669,15 @@
static void
nAllocationGenerateMipmaps(JNIEnv *_env, jobject _this, jlong con, jlong alloc)
{
- LOG_API("nAllocationGenerateMipmaps, con(%p), a(%p)", (RsContext)con, (RsAllocation)alloc);
+ if (kLogApi) {
+ ALOGD("nAllocationGenerateMipmaps, con(%p), a(%p)", (RsContext)con, (RsAllocation)alloc);
+ }
rsAllocationGenerateMipmaps((RsContext)con, (RsAllocation)alloc);
}
static jlong
-nAllocationCreateFromBitmap(JNIEnv *_env, jobject _this, jlong con, jlong type, jint mip, jobject jbitmap, jint usage)
+nAllocationCreateFromBitmap(JNIEnv *_env, jobject _this, jlong con, jlong type, jint mip,
+ jobject jbitmap, jint usage)
{
SkBitmap const * nativeBitmap =
(SkBitmap const *)_env->GetLongField(jbitmap, gNativeBitmapID);
@@ -608,7 +693,8 @@
}
static jlong
-nAllocationCreateBitmapBackedAllocation(JNIEnv *_env, jobject _this, jlong con, jlong type, jint mip, jobject jbitmap, jint usage)
+nAllocationCreateBitmapBackedAllocation(JNIEnv *_env, jobject _this, jlong con, jlong type,
+ jint mip, jobject jbitmap, jint usage)
{
SkBitmap const * nativeBitmap =
(SkBitmap const *)_env->GetLongField(jbitmap, gNativeBitmapID);
@@ -624,7 +710,8 @@
}
static jlong
-nAllocationCubeCreateFromBitmap(JNIEnv *_env, jobject _this, jlong con, jlong type, jint mip, jobject jbitmap, jint usage)
+nAllocationCubeCreateFromBitmap(JNIEnv *_env, jobject _this, jlong con, jlong type, jint mip,
+ jobject jbitmap, jint usage)
{
SkBitmap const * nativeBitmap =
(SkBitmap const *)_env->GetLongField(jbitmap, gNativeBitmapID);
@@ -670,32 +757,34 @@
bitmap.notifyPixelsChanged();
}
-static void ReleaseBitmapCallback(void *bmp)
-{
- SkBitmap const * nativeBitmap = (SkBitmap const *)bmp;
- nativeBitmap->unlockPixels();
-}
-
-
// Copies from the Java object data into the Allocation pointed to by _alloc.
static void
nAllocationData1D(JNIEnv *_env, jobject _this, jlong con, jlong _alloc, jint offset, jint lod,
jint count, jobject data, jint sizeBytes, jint dataType)
{
RsAllocation *alloc = (RsAllocation *)_alloc;
- LOG_API("nAllocation1DData, con(%p), adapter(%p), offset(%i), count(%i), sizeBytes(%i), dataType(%i)",
- (RsContext)con, (RsAllocation)alloc, offset, count, sizeBytes, dataType);
- PER_ARRAY_TYPE(NULL, rsAllocation1DData, true, (RsContext)con, alloc, offset, lod, count, ptr, sizeBytes);
+ if (kLogApi) {
+ ALOGD("nAllocation1DData, con(%p), adapter(%p), offset(%i), count(%i), sizeBytes(%i), "
+ "dataType(%i)", (RsContext)con, (RsAllocation)alloc, offset, count, sizeBytes,
+ dataType);
+ }
+ PER_ARRAY_TYPE(nullptr, rsAllocation1DData, true, (RsContext)con, alloc, offset, lod, count,
+ ptr, sizeBytes);
}
// Copies from the Java array data into the Allocation pointed to by alloc.
static void
// native void rsnAllocationElementData1D(long con, long id, int xoff, int compIdx, byte[] d, int sizeBytes);
-nAllocationElementData1D(JNIEnv *_env, jobject _this, jlong con, jlong alloc, jint offset, jint lod, jint compIdx, jbyteArray data, jint sizeBytes)
+nAllocationElementData1D(JNIEnv *_env, jobject _this, jlong con, jlong alloc, jint offset, jint lod,
+ jint compIdx, jbyteArray data, jint sizeBytes)
{
jint len = _env->GetArrayLength(data);
- LOG_API("nAllocationElementData1D, con(%p), alloc(%p), offset(%i), comp(%i), len(%i), sizeBytes(%i)", (RsContext)con, (RsAllocation)alloc, offset, compIdx, len, sizeBytes);
- jbyte *ptr = _env->GetByteArrayElements(data, NULL);
+ if (kLogApi) {
+ ALOGD("nAllocationElementData1D, con(%p), alloc(%p), offset(%i), comp(%i), len(%i), "
+ "sizeBytes(%i)", (RsContext)con, (RsAllocation)alloc, offset, compIdx, len,
+ sizeBytes);
+ }
+ jbyte *ptr = _env->GetByteArrayElements(data, nullptr);
rsAllocation1DElementData((RsContext)con, (RsAllocation)alloc, offset, lod, ptr, sizeBytes, compIdx);
_env->ReleaseByteArrayElements(data, ptr, JNI_ABORT);
}
@@ -707,9 +796,11 @@
{
RsAllocation *alloc = (RsAllocation *)_alloc;
RsAllocationCubemapFace face = (RsAllocationCubemapFace)_face;
- LOG_API("nAllocation2DData, con(%p), adapter(%p), xoff(%i), yoff(%i), w(%i), h(%i), len(%i) type(%i)",
- (RsContext)con, alloc, xoff, yoff, w, h, sizeBytes, dataType);
- PER_ARRAY_TYPE(NULL, rsAllocation2DData, true, (RsContext)con, alloc, xoff, yoff, lod, face, w, h, ptr, sizeBytes, 0);
+ if (kLogApi) {
+ ALOGD("nAllocation2DData, con(%p), adapter(%p), xoff(%i), yoff(%i), w(%i), h(%i), len(%i) "
+ "type(%i)", (RsContext)con, alloc, xoff, yoff, w, h, sizeBytes, dataType);
+ }
+ PER_ARRAY_TYPE(nullptr, rsAllocation2DData, true, (RsContext)con, alloc, xoff, yoff, lod, face, w, h, ptr, sizeBytes, 0);
}
// Copies from the Allocation pointed to by srcAlloc into the Allocation
@@ -722,11 +813,13 @@
jlong srcAlloc, jint srcXoff, jint srcYoff,
jint srcMip, jint srcFace)
{
- LOG_API("nAllocation2DData_s, con(%p), dstAlloc(%p), dstXoff(%i), dstYoff(%i),"
- " dstMip(%i), dstFace(%i), width(%i), height(%i),"
- " srcAlloc(%p), srcXoff(%i), srcYoff(%i), srcMip(%i), srcFace(%i)",
- (RsContext)con, (RsAllocation)dstAlloc, dstXoff, dstYoff, dstMip, dstFace,
- width, height, (RsAllocation)srcAlloc, srcXoff, srcYoff, srcMip, srcFace);
+ if (kLogApi) {
+ ALOGD("nAllocation2DData_s, con(%p), dstAlloc(%p), dstXoff(%i), dstYoff(%i),"
+ " dstMip(%i), dstFace(%i), width(%i), height(%i),"
+ " srcAlloc(%p), srcXoff(%i), srcYoff(%i), srcMip(%i), srcFace(%i)",
+ (RsContext)con, (RsAllocation)dstAlloc, dstXoff, dstYoff, dstMip, dstFace,
+ width, height, (RsAllocation)srcAlloc, srcXoff, srcYoff, srcMip, srcFace);
+ }
rsAllocationCopy2DRange((RsContext)con,
(RsAllocation)dstAlloc,
@@ -744,9 +837,12 @@
jint w, jint h, jint d, jobject data, int sizeBytes, int dataType)
{
RsAllocation *alloc = (RsAllocation *)_alloc;
- LOG_API("nAllocation3DData, con(%p), alloc(%p), xoff(%i), yoff(%i), zoff(%i), lod(%i), w(%i), h(%i), d(%i), sizeBytes(%i)",
- (RsContext)con, (RsAllocation)alloc, xoff, yoff, zoff, lod, w, h, d, sizeBytes);
- PER_ARRAY_TYPE(NULL, rsAllocation3DData, true, (RsContext)con, alloc, xoff, yoff, zoff, lod, w, h, d, ptr, sizeBytes, 0);
+ if (kLogApi) {
+ ALOGD("nAllocation3DData, con(%p), alloc(%p), xoff(%i), yoff(%i), zoff(%i), lod(%i), w(%i),"
+ " h(%i), d(%i), sizeBytes(%i)", (RsContext)con, (RsAllocation)alloc, xoff, yoff, zoff,
+ lod, w, h, d, sizeBytes);
+ }
+ PER_ARRAY_TYPE(nullptr, rsAllocation3DData, true, (RsContext)con, alloc, xoff, yoff, zoff, lod, w, h, d, ptr, sizeBytes, 0);
}
// Copies from the Allocation pointed to by srcAlloc into the Allocation
@@ -759,11 +855,13 @@
jlong srcAlloc, jint srcXoff, jint srcYoff, jint srcZoff,
jint srcMip)
{
- LOG_API("nAllocationData3D_alloc, con(%p), dstAlloc(%p), dstXoff(%i), dstYoff(%i),"
- " dstMip(%i), width(%i), height(%i),"
- " srcAlloc(%p), srcXoff(%i), srcYoff(%i), srcMip(%i)",
- (RsContext)con, (RsAllocation)dstAlloc, dstXoff, dstYoff, dstMip,
- width, height, (RsAllocation)srcAlloc, srcXoff, srcYoff, srcMip);
+ if (kLogApi) {
+ ALOGD("nAllocationData3D_alloc, con(%p), dstAlloc(%p), dstXoff(%i), dstYoff(%i),"
+ " dstMip(%i), width(%i), height(%i),"
+ " srcAlloc(%p), srcXoff(%i), srcYoff(%i), srcMip(%i)",
+ (RsContext)con, (RsAllocation)dstAlloc, dstXoff, dstYoff, dstMip,
+ width, height, (RsAllocation)srcAlloc, srcXoff, srcYoff, srcMip);
+ }
rsAllocationCopy3DRange((RsContext)con,
(RsAllocation)dstAlloc,
@@ -779,7 +877,9 @@
nAllocationRead(JNIEnv *_env, jobject _this, jlong con, jlong _alloc, jobject data, int dataType)
{
RsAllocation *alloc = (RsAllocation *)_alloc;
- LOG_API("nAllocationRead, con(%p), alloc(%p)", (RsContext)con, (RsAllocation)alloc);
+ if (kLogApi) {
+ ALOGD("nAllocationRead, con(%p), alloc(%p)", (RsContext)con, (RsAllocation)alloc);
+ }
PER_ARRAY_TYPE(0, rsAllocationRead, false, (RsContext)con, alloc, ptr, len * typeBytes);
}
@@ -789,8 +889,10 @@
jint count, jobject data, int sizeBytes, int dataType)
{
RsAllocation *alloc = (RsAllocation *)_alloc;
- LOG_API("nAllocation1DRead, con(%p), adapter(%p), offset(%i), count(%i), sizeBytes(%i), dataType(%i)",
- (RsContext)con, alloc, offset, count, sizeBytes, dataType);
+ if (kLogApi) {
+ ALOGD("nAllocation1DRead, con(%p), adapter(%p), offset(%i), count(%i), sizeBytes(%i), "
+ "dataType(%i)", (RsContext)con, alloc, offset, count, sizeBytes, dataType);
+ }
PER_ARRAY_TYPE(0, rsAllocation1DRead, false, (RsContext)con, alloc, offset, lod, count, ptr, sizeBytes);
}
@@ -801,22 +903,30 @@
{
RsAllocation *alloc = (RsAllocation *)_alloc;
RsAllocationCubemapFace face = (RsAllocationCubemapFace)_face;
- LOG_API("nAllocation2DRead, con(%p), adapter(%p), xoff(%i), yoff(%i), w(%i), h(%i), len(%i) type(%i)",
- (RsContext)con, alloc, xoff, yoff, w, h, sizeBytes, dataType);
- PER_ARRAY_TYPE(0, rsAllocation2DRead, false, (RsContext)con, alloc, xoff, yoff, lod, face, w, h, ptr, sizeBytes, 0);
+ if (kLogApi) {
+ ALOGD("nAllocation2DRead, con(%p), adapter(%p), xoff(%i), yoff(%i), w(%i), h(%i), len(%i) "
+ "type(%i)", (RsContext)con, alloc, xoff, yoff, w, h, sizeBytes, dataType);
+ }
+ PER_ARRAY_TYPE(0, rsAllocation2DRead, false, (RsContext)con, alloc, xoff, yoff, lod, face, w, h,
+ ptr, sizeBytes, 0);
}
static jlong
nAllocationGetType(JNIEnv *_env, jobject _this, jlong con, jlong a)
{
- LOG_API("nAllocationGetType, con(%p), a(%p)", (RsContext)con, (RsAllocation)a);
+ if (kLogApi) {
+ ALOGD("nAllocationGetType, con(%p), a(%p)", (RsContext)con, (RsAllocation)a);
+ }
return (jlong)(uintptr_t) rsaAllocationGetType((RsContext)con, (RsAllocation)a);
}
static void
nAllocationResize1D(JNIEnv *_env, jobject _this, jlong con, jlong alloc, jint dimX)
{
- LOG_API("nAllocationResize1D, con(%p), alloc(%p), sizeX(%i)", (RsContext)con, (RsAllocation)alloc, dimX);
+ if (kLogApi) {
+ ALOGD("nAllocationResize1D, con(%p), alloc(%p), sizeX(%i)", (RsContext)con,
+ (RsAllocation)alloc, dimX);
+ }
rsAllocationResize1D((RsContext)con, (RsAllocation)alloc, dimX);
}
@@ -836,13 +946,13 @@
nFileA3DCreateFromAsset(JNIEnv *_env, jobject _this, jlong con, jobject _assetMgr, jstring _path)
{
AssetManager* mgr = assetManagerForJavaObject(_env, _assetMgr);
- if (mgr == NULL) {
+ if (mgr == nullptr) {
return 0;
}
AutoJavaStringToUTF8 str(_env, _path);
Asset* asset = mgr->open(str.c_str(), Asset::ACCESS_BUFFER);
- if (asset == NULL) {
+ if (asset == nullptr) {
return 0;
}
@@ -924,13 +1034,13 @@
jfloat fontSize, jint dpi)
{
AssetManager* mgr = assetManagerForJavaObject(_env, _assetMgr);
- if (mgr == NULL) {
+ if (mgr == nullptr) {
return 0;
}
AutoJavaStringToUTF8 str(_env, _path);
Asset* asset = mgr->open(str.c_str(), Asset::ACCESS_BUFFER);
- if (asset == NULL) {
+ if (asset == nullptr) {
return 0;
}
@@ -947,21 +1057,29 @@
static void
nScriptBindAllocation(JNIEnv *_env, jobject _this, jlong con, jlong script, jlong alloc, jint slot)
{
- LOG_API("nScriptBindAllocation, con(%p), script(%p), alloc(%p), slot(%i)", (RsContext)con, (RsScript)script, (RsAllocation)alloc, slot);
+ if (kLogApi) {
+ ALOGD("nScriptBindAllocation, con(%p), script(%p), alloc(%p), slot(%i)", (RsContext)con,
+ (RsScript)script, (RsAllocation)alloc, slot);
+ }
rsScriptBindAllocation((RsContext)con, (RsScript)script, (RsAllocation)alloc, slot);
}
static void
nScriptSetVarI(JNIEnv *_env, jobject _this, jlong con, jlong script, jint slot, jint val)
{
- LOG_API("nScriptSetVarI, con(%p), s(%p), slot(%i), val(%i)", (RsContext)con, (void *)script, slot, val);
+ if (kLogApi) {
+ ALOGD("nScriptSetVarI, con(%p), s(%p), slot(%i), val(%i)", (RsContext)con, (void *)script,
+ slot, val);
+ }
rsScriptSetVarI((RsContext)con, (RsScript)script, slot, val);
}
static jint
nScriptGetVarI(JNIEnv *_env, jobject _this, jlong con, jlong script, jint slot)
{
- LOG_API("nScriptGetVarI, con(%p), s(%p), slot(%i)", (RsContext)con, (void *)script, slot);
+ if (kLogApi) {
+ ALOGD("nScriptGetVarI, con(%p), s(%p), slot(%i)", (RsContext)con, (void *)script, slot);
+ }
int value = 0;
rsScriptGetVarV((RsContext)con, (RsScript)script, slot, &value, sizeof(value));
return value;
@@ -970,21 +1088,29 @@
static void
nScriptSetVarObj(JNIEnv *_env, jobject _this, jlong con, jlong script, jint slot, jlong val)
{
- LOG_API("nScriptSetVarObj, con(%p), s(%p), slot(%i), val(%i)", (RsContext)con, (void *)script, slot, val);
+ if (kLogApi) {
+ ALOGD("nScriptSetVarObj, con(%p), s(%p), slot(%i), val(%i)", (RsContext)con, (void *)script,
+ slot, val);
+ }
rsScriptSetVarObj((RsContext)con, (RsScript)script, slot, (RsObjectBase)val);
}
static void
nScriptSetVarJ(JNIEnv *_env, jobject _this, jlong con, jlong script, jint slot, jlong val)
{
- LOG_API("nScriptSetVarJ, con(%p), s(%p), slot(%i), val(%lli)", (RsContext)con, (void *)script, slot, val);
+ if (kLogApi) {
+ ALOGD("nScriptSetVarJ, con(%p), s(%p), slot(%i), val(%lli)", (RsContext)con, (void *)script,
+ slot, val);
+ }
rsScriptSetVarJ((RsContext)con, (RsScript)script, slot, val);
}
static jlong
nScriptGetVarJ(JNIEnv *_env, jobject _this, jlong con, jlong script, jint slot)
{
- LOG_API("nScriptGetVarJ, con(%p), s(%p), slot(%i)", (RsContext)con, (void *)script, slot);
+ if (kLogApi) {
+ ALOGD("nScriptGetVarJ, con(%p), s(%p), slot(%i)", (RsContext)con, (void *)script, slot);
+ }
jlong value = 0;
rsScriptGetVarV((RsContext)con, (RsScript)script, slot, &value, sizeof(value));
return value;
@@ -993,14 +1119,19 @@
static void
nScriptSetVarF(JNIEnv *_env, jobject _this, jlong con, jlong script, jint slot, float val)
{
- LOG_API("nScriptSetVarF, con(%p), s(%p), slot(%i), val(%f)", (RsContext)con, (void *)script, slot, val);
+ if (kLogApi) {
+ ALOGD("nScriptSetVarF, con(%p), s(%p), slot(%i), val(%f)", (RsContext)con, (void *)script,
+ slot, val);
+ }
rsScriptSetVarF((RsContext)con, (RsScript)script, slot, val);
}
static jfloat
nScriptGetVarF(JNIEnv *_env, jobject _this, jlong con, jlong script, jint slot)
{
- LOG_API("nScriptGetVarF, con(%p), s(%p), slot(%i)", (RsContext)con, (void *)script, slot);
+ if (kLogApi) {
+ ALOGD("nScriptGetVarF, con(%p), s(%p), slot(%i)", (RsContext)con, (void *)script, slot);
+ }
jfloat value = 0;
rsScriptGetVarV((RsContext)con, (RsScript)script, slot, &value, sizeof(value));
return value;
@@ -1009,14 +1140,19 @@
static void
nScriptSetVarD(JNIEnv *_env, jobject _this, jlong con, jlong script, jint slot, double val)
{
- LOG_API("nScriptSetVarD, con(%p), s(%p), slot(%i), val(%lf)", (RsContext)con, (void *)script, slot, val);
+ if (kLogApi) {
+ ALOGD("nScriptSetVarD, con(%p), s(%p), slot(%i), val(%lf)", (RsContext)con, (void *)script,
+ slot, val);
+ }
rsScriptSetVarD((RsContext)con, (RsScript)script, slot, val);
}
static jdouble
nScriptGetVarD(JNIEnv *_env, jobject _this, jlong con, jlong script, jint slot)
{
- LOG_API("nScriptGetVarD, con(%p), s(%p), slot(%i)", (RsContext)con, (void *)script, slot);
+ if (kLogApi) {
+ ALOGD("nScriptGetVarD, con(%p), s(%p), slot(%i)", (RsContext)con, (void *)script, slot);
+ }
jdouble value = 0;
rsScriptGetVarV((RsContext)con, (RsScript)script, slot, &value, sizeof(value));
return value;
@@ -1025,9 +1161,11 @@
static void
nScriptSetVarV(JNIEnv *_env, jobject _this, jlong con, jlong script, jint slot, jbyteArray data)
{
- LOG_API("nScriptSetVarV, con(%p), s(%p), slot(%i)", (RsContext)con, (void *)script, slot);
+ if (kLogApi) {
+ ALOGD("nScriptSetVarV, con(%p), s(%p), slot(%i)", (RsContext)con, (void *)script, slot);
+ }
jint len = _env->GetArrayLength(data);
- jbyte *ptr = _env->GetByteArrayElements(data, NULL);
+ jbyte *ptr = _env->GetByteArrayElements(data, nullptr);
rsScriptSetVarV((RsContext)con, (RsScript)script, slot, ptr, len);
_env->ReleaseByteArrayElements(data, ptr, JNI_ABORT);
}
@@ -1035,21 +1173,26 @@
static void
nScriptGetVarV(JNIEnv *_env, jobject _this, jlong con, jlong script, jint slot, jbyteArray data)
{
- LOG_API("nScriptSetVarV, con(%p), s(%p), slot(%i)", (RsContext)con, (void *)script, slot);
+ if (kLogApi) {
+ ALOGD("nScriptSetVarV, con(%p), s(%p), slot(%i)", (RsContext)con, (void *)script, slot);
+ }
jint len = _env->GetArrayLength(data);
- jbyte *ptr = _env->GetByteArrayElements(data, NULL);
+ jbyte *ptr = _env->GetByteArrayElements(data, nullptr);
rsScriptGetVarV((RsContext)con, (RsScript)script, slot, ptr, len);
_env->ReleaseByteArrayElements(data, ptr, 0);
}
static void
-nScriptSetVarVE(JNIEnv *_env, jobject _this, jlong con, jlong script, jint slot, jbyteArray data, jlong elem, jintArray dims)
+nScriptSetVarVE(JNIEnv *_env, jobject _this, jlong con, jlong script, jint slot, jbyteArray data,
+ jlong elem, jintArray dims)
{
- LOG_API("nScriptSetVarVE, con(%p), s(%p), slot(%i)", (RsContext)con, (void *)script, slot);
+ if (kLogApi) {
+ ALOGD("nScriptSetVarVE, con(%p), s(%p), slot(%i)", (RsContext)con, (void *)script, slot);
+ }
jint len = _env->GetArrayLength(data);
- jbyte *ptr = _env->GetByteArrayElements(data, NULL);
+ jbyte *ptr = _env->GetByteArrayElements(data, nullptr);
jint dimsLen = _env->GetArrayLength(dims) * sizeof(int);
- jint *dimsPtr = _env->GetIntArrayElements(dims, NULL);
+ jint *dimsPtr = _env->GetIntArrayElements(dims, nullptr);
rsScriptSetVarVE((RsContext)con, (RsScript)script, slot, ptr, len, (RsElement)elem,
(const uint32_t*) dimsPtr, dimsLen);
_env->ReleaseByteArrayElements(data, ptr, JNI_ABORT);
@@ -1060,7 +1203,9 @@
static void
nScriptSetTimeZone(JNIEnv *_env, jobject _this, jlong con, jlong script, jbyteArray timeZone)
{
- LOG_API("nScriptCSetTimeZone, con(%p), s(%p)", (RsContext)con, (void *)script);
+ if (kLogApi) {
+ ALOGD("nScriptCSetTimeZone, con(%p), s(%p)", (RsContext)con, (void *)script);
+ }
jint length = _env->GetArrayLength(timeZone);
jbyte* timeZone_ptr;
@@ -1076,174 +1221,103 @@
static void
nScriptInvoke(JNIEnv *_env, jobject _this, jlong con, jlong obj, jint slot)
{
- LOG_API("nScriptInvoke, con(%p), script(%p)", (RsContext)con, (void *)obj);
+ if (kLogApi) {
+ ALOGD("nScriptInvoke, con(%p), script(%p)", (RsContext)con, (void *)obj);
+ }
rsScriptInvoke((RsContext)con, (RsScript)obj, slot);
}
static void
nScriptInvokeV(JNIEnv *_env, jobject _this, jlong con, jlong script, jint slot, jbyteArray data)
{
- LOG_API("nScriptInvokeV, con(%p), s(%p), slot(%i)", (RsContext)con, (void *)script, slot);
+ if (kLogApi) {
+ ALOGD("nScriptInvokeV, con(%p), s(%p), slot(%i)", (RsContext)con, (void *)script, slot);
+ }
jint len = _env->GetArrayLength(data);
- jbyte *ptr = _env->GetByteArrayElements(data, NULL);
+ jbyte *ptr = _env->GetByteArrayElements(data, nullptr);
rsScriptInvokeV((RsContext)con, (RsScript)script, slot, ptr, len);
_env->ReleaseByteArrayElements(data, ptr, JNI_ABORT);
}
static void
-nScriptForEach(JNIEnv *_env, jobject _this, jlong con,
- jlong script, jint slot, jlong ain, jlong aout)
+nScriptForEach(JNIEnv *_env, jobject _this, jlong con, jlong script, jint slot,
+ jlongArray ains, jlong aout, jbyteArray params,
+ jintArray limits)
{
- LOG_API("nScriptForEach, con(%p), s(%p), slot(%i)", (RsContext)con, (void *)script, slot);
- rsScriptForEach((RsContext)con, (RsScript)script, slot, (RsAllocation)ain, (RsAllocation)aout, NULL, 0, NULL, 0);
-}
-static void
-nScriptForEachV(JNIEnv *_env, jobject _this, jlong con,
- jlong script, jint slot, jlong ain, jlong aout, jbyteArray params)
-{
- LOG_API("nScriptForEach, con(%p), s(%p), slot(%i)", (RsContext)con, (void *)script, slot);
- jint len = _env->GetArrayLength(params);
- jbyte *ptr = _env->GetByteArrayElements(params, NULL);
- rsScriptForEach((RsContext)con, (RsScript)script, slot, (RsAllocation)ain, (RsAllocation)aout, ptr, len, NULL, 0);
- _env->ReleaseByteArrayElements(params, ptr, JNI_ABORT);
-}
-
-static void
-nScriptForEachClipped(JNIEnv *_env, jobject _this, jlong con,
- jlong script, jint slot, jlong ain, jlong aout,
- jint xstart, jint xend,
- jint ystart, jint yend, jint zstart, jint zend)
-{
- LOG_API("nScriptForEachClipped, con(%p), s(%p), slot(%i)", (RsContext)con, (void *)script, slot);
- RsScriptCall sc;
- sc.xStart = xstart;
- sc.xEnd = xend;
- sc.yStart = ystart;
- sc.yEnd = yend;
- sc.zStart = zstart;
- sc.zEnd = zend;
- sc.strategy = RS_FOR_EACH_STRATEGY_DONT_CARE;
- sc.arrayStart = 0;
- sc.arrayEnd = 0;
- rsScriptForEach((RsContext)con, (RsScript)script, slot, (RsAllocation)ain, (RsAllocation)aout, NULL, 0, &sc, sizeof(sc));
-}
-
-static void
-nScriptForEachClippedV(JNIEnv *_env, jobject _this, jlong con,
- jlong script, jint slot, jlong ain, jlong aout,
- jbyteArray params, jint xstart, jint xend,
- jint ystart, jint yend, jint zstart, jint zend)
-{
- LOG_API("nScriptForEachClipped, con(%p), s(%p), slot(%i)", (RsContext)con, (void *)script, slot);
- jint len = _env->GetArrayLength(params);
- jbyte *ptr = _env->GetByteArrayElements(params, NULL);
- RsScriptCall sc;
- sc.xStart = xstart;
- sc.xEnd = xend;
- sc.yStart = ystart;
- sc.yEnd = yend;
- sc.zStart = zstart;
- sc.zEnd = zend;
- sc.strategy = RS_FOR_EACH_STRATEGY_DONT_CARE;
- sc.arrayStart = 0;
- sc.arrayEnd = 0;
- rsScriptForEach((RsContext)con, (RsScript)script, slot, (RsAllocation)ain, (RsAllocation)aout, ptr, len, &sc, sizeof(sc));
- _env->ReleaseByteArrayElements(params, ptr, JNI_ABORT);
-}
-
-static void
-nScriptForEachMultiClipped(JNIEnv *_env, jobject _this, jlong con,
- jlong script, jint slot, jlongArray ains, jlong aout,
- jint xstart, jint xend,
- jint ystart, jint yend, jint zstart, jint zend)
-{
- LOG_API("nScriptForEachMultiClipped, con(%p), s(%p), slot(%i)", (RsContext)con, (void *)script, slot);
-
- jint in_len = _env->GetArrayLength(ains);
- jlong* in_ptr = _env->GetLongArrayElements(ains, NULL);
-
- RsAllocation *in_allocs = NULL;
-
- if (sizeof(RsAllocation) == sizeof(jlong)) {
- in_allocs = (RsAllocation*)in_ptr;
-
- } else {
- // Convert from 64-bit jlong types to the native pointer type.
-
- in_allocs = new RsAllocation[in_len];
-
- for (int index = in_len; --index >= 0;) {
- in_allocs[index] = (RsAllocation)in_ptr[index];
- }
+ if (kLogApi) {
+ ALOGD("nScriptForEach, con(%p), s(%p), slot(%i)", (RsContext)con, (void *)script, slot);
}
- RsScriptCall sc;
- sc.xStart = xstart;
- sc.xEnd = xend;
- sc.yStart = ystart;
- sc.yEnd = yend;
- sc.zStart = zstart;
- sc.zEnd = zend;
- sc.strategy = RS_FOR_EACH_STRATEGY_DONT_CARE;
- sc.arrayStart = 0;
- sc.arrayEnd = 0;
+ jint in_len = 0;
+ jlong *in_ptr = nullptr;
- rsScriptForEachMulti((RsContext)con, (RsScript)script, slot, in_allocs, in_len, (RsAllocation)aout, NULL, 0, &sc, sizeof(sc));
+ RsAllocation *in_allocs = nullptr;
- if (sizeof(RsAllocation) != sizeof(jlong)) {
- delete[] in_allocs;
+ if (ains != nullptr) {
+ in_len = _env->GetArrayLength(ains);
+ in_ptr = _env->GetLongArrayElements(ains, nullptr);
+
+ if (sizeof(RsAllocation) == sizeof(jlong)) {
+ in_allocs = (RsAllocation*)in_ptr;
+
+ } else {
+ // Convert from 64-bit jlong types to the native pointer type.
+
+ in_allocs = (RsAllocation*)alloca(in_len * sizeof(RsAllocation));
+
+ for (int index = in_len; --index >= 0;) {
+ in_allocs[index] = (RsAllocation)in_ptr[index];
+ }
+ }
}
- _env->ReleaseLongArrayElements(ains, in_ptr, JNI_ABORT);
-}
+ jint param_len = 0;
+ jbyte *param_ptr = nullptr;
-static void
-nScriptForEachMultiClippedV(JNIEnv *_env, jobject _this, jlong con,
- jlong script, jint slot, jlongArray ains, jlong aout,
- jbyteArray params, jint xstart, jint xend,
- jint ystart, jint yend, jint zstart, jint zend)
-{
- LOG_API("nScriptForEachMultiClippedV, con(%p), s(%p), slot(%i)", (RsContext)con, (void *)script, slot);
-
- jint in_len = _env->GetArrayLength(ains);
- jlong* in_ptr = _env->GetLongArrayElements(ains, NULL);
-
- RsAllocation *in_allocs = NULL;
-
- if (sizeof(RsAllocation) == sizeof(jlong)) {
- in_allocs = (RsAllocation*)in_ptr;
-
- } else {
- // Convert from 64-bit jlong types to the native pointer type.
-
- in_allocs = new RsAllocation[in_len];
-
- for (int index = in_len; --index >= 0;) {
- in_allocs[index] = (RsAllocation)in_ptr[index];
- }
+ if (params != nullptr) {
+ param_len = _env->GetArrayLength(params);
+ param_ptr = _env->GetByteArrayElements(params, nullptr);
}
- jint param_len = _env->GetArrayLength(params);
- jbyte* param_ptr = _env->GetByteArrayElements(params, NULL);
+ RsScriptCall sc, *sca = nullptr;
+ uint32_t sc_size = 0;
- RsScriptCall sc;
- sc.xStart = xstart;
- sc.xEnd = xend;
- sc.yStart = ystart;
- sc.yEnd = yend;
- sc.zStart = zstart;
- sc.zEnd = zend;
- sc.strategy = RS_FOR_EACH_STRATEGY_DONT_CARE;
- sc.arrayStart = 0;
- sc.arrayEnd = 0;
- rsScriptForEachMulti((RsContext)con, (RsScript)script, slot, in_allocs, in_len, (RsAllocation)aout, param_ptr, param_len, &sc, sizeof(sc));
+ jint limit_len = 0;
+ jint *limit_ptr = nullptr;
- if (sizeof(RsAllocation) != sizeof(jlong)) {
- delete[] in_allocs;
+ if (limits != nullptr) {
+ limit_len = _env->GetArrayLength(limits);
+ limit_ptr = _env->GetIntArrayElements(limits, nullptr);
+
+ assert(limit_len == 6);
+ UNUSED(limit_len); // As the assert might not be compiled.
+
+ sc.xStart = limit_ptr[0];
+ sc.xEnd = limit_ptr[1];
+ sc.yStart = limit_ptr[2];
+ sc.yEnd = limit_ptr[3];
+ sc.zStart = limit_ptr[4];
+ sc.zEnd = limit_ptr[5];
+ sc.strategy = RS_FOR_EACH_STRATEGY_DONT_CARE;
+
+ sca = ≻
}
- _env->ReleaseLongArrayElements(ains, in_ptr, JNI_ABORT);
- _env->ReleaseByteArrayElements(params, param_ptr, JNI_ABORT);
+ rsScriptForEachMulti((RsContext)con, (RsScript)script, slot,
+ in_allocs, in_len, (RsAllocation)aout,
+ param_ptr, param_len, sca, sc_size);
+
+ if (ains != nullptr) {
+ _env->ReleaseLongArrayElements(ains, in_ptr, JNI_ABORT);
+ }
+
+ if (params != nullptr) {
+ _env->ReleaseByteArrayElements(params, param_ptr, JNI_ABORT);
+ }
+
+ if (limits != nullptr) {
+ _env->ReleaseIntArrayElements(limits, limit_ptr, JNI_ABORT);
+ }
}
// -----------------------------------
@@ -1253,12 +1327,14 @@
jstring resName, jstring cacheDir,
jbyteArray scriptRef, jint length)
{
- LOG_API("nScriptCCreate, con(%p)", (RsContext)con);
+ if (kLogApi) {
+ ALOGD("nScriptCCreate, con(%p)", (RsContext)con);
+ }
AutoJavaStringToUTF8 resNameUTF(_env, resName);
AutoJavaStringToUTF8 cacheDirUTF(_env, cacheDir);
jlong ret = 0;
- jbyte* script_ptr = NULL;
+ jbyte* script_ptr = nullptr;
jint _exception = 0;
jint remaining;
if (!scriptRef) {
@@ -1300,21 +1376,30 @@
static jlong
nScriptIntrinsicCreate(JNIEnv *_env, jobject _this, jlong con, jint id, jlong eid)
{
- LOG_API("nScriptIntrinsicCreate, con(%p) id(%i) element(%p)", (RsContext)con, id, (void *)eid);
+ if (kLogApi) {
+ ALOGD("nScriptIntrinsicCreate, con(%p) id(%i) element(%p)", (RsContext)con, id,
+ (void *)eid);
+ }
return (jlong)(uintptr_t)rsScriptIntrinsicCreate((RsContext)con, id, (RsElement)eid);
}
static jlong
nScriptKernelIDCreate(JNIEnv *_env, jobject _this, jlong con, jlong sid, jint slot, jint sig)
{
- LOG_API("nScriptKernelIDCreate, con(%p) script(%p), slot(%i), sig(%i)", (RsContext)con, (void *)sid, slot, sig);
+ if (kLogApi) {
+ ALOGD("nScriptKernelIDCreate, con(%p) script(%p), slot(%i), sig(%i)", (RsContext)con,
+ (void *)sid, slot, sig);
+ }
return (jlong)(uintptr_t)rsScriptKernelIDCreate((RsContext)con, (RsScript)sid, slot, sig);
}
static jlong
nScriptFieldIDCreate(JNIEnv *_env, jobject _this, jlong con, jlong sid, jint slot)
{
- LOG_API("nScriptFieldIDCreate, con(%p) script(%p), slot(%i)", (RsContext)con, (void *)sid, slot);
+ if (kLogApi) {
+ ALOGD("nScriptFieldIDCreate, con(%p) script(%p), slot(%i)", (RsContext)con, (void *)sid,
+ slot);
+ }
return (jlong)(uintptr_t)rsScriptFieldIDCreate((RsContext)con, (RsScript)sid, slot);
}
@@ -1322,38 +1407,40 @@
nScriptGroupCreate(JNIEnv *_env, jobject _this, jlong con, jlongArray _kernels, jlongArray _src,
jlongArray _dstk, jlongArray _dstf, jlongArray _types)
{
- LOG_API("nScriptGroupCreate, con(%p)", (RsContext)con);
+ if (kLogApi) {
+ ALOGD("nScriptGroupCreate, con(%p)", (RsContext)con);
+ }
jint kernelsLen = _env->GetArrayLength(_kernels);
- jlong *jKernelsPtr = _env->GetLongArrayElements(_kernels, NULL);
+ jlong *jKernelsPtr = _env->GetLongArrayElements(_kernels, nullptr);
RsScriptKernelID* kernelsPtr = (RsScriptKernelID*) malloc(sizeof(RsScriptKernelID) * kernelsLen);
for(int i = 0; i < kernelsLen; ++i) {
kernelsPtr[i] = (RsScriptKernelID)jKernelsPtr[i];
}
jint srcLen = _env->GetArrayLength(_src);
- jlong *jSrcPtr = _env->GetLongArrayElements(_src, NULL);
+ jlong *jSrcPtr = _env->GetLongArrayElements(_src, nullptr);
RsScriptKernelID* srcPtr = (RsScriptKernelID*) malloc(sizeof(RsScriptKernelID) * srcLen);
for(int i = 0; i < srcLen; ++i) {
srcPtr[i] = (RsScriptKernelID)jSrcPtr[i];
}
jint dstkLen = _env->GetArrayLength(_dstk);
- jlong *jDstkPtr = _env->GetLongArrayElements(_dstk, NULL);
+ jlong *jDstkPtr = _env->GetLongArrayElements(_dstk, nullptr);
RsScriptKernelID* dstkPtr = (RsScriptKernelID*) malloc(sizeof(RsScriptKernelID) * dstkLen);
for(int i = 0; i < dstkLen; ++i) {
dstkPtr[i] = (RsScriptKernelID)jDstkPtr[i];
}
jint dstfLen = _env->GetArrayLength(_dstf);
- jlong *jDstfPtr = _env->GetLongArrayElements(_dstf, NULL);
+ jlong *jDstfPtr = _env->GetLongArrayElements(_dstf, nullptr);
RsScriptKernelID* dstfPtr = (RsScriptKernelID*) malloc(sizeof(RsScriptKernelID) * dstfLen);
for(int i = 0; i < dstfLen; ++i) {
dstfPtr[i] = (RsScriptKernelID)jDstfPtr[i];
}
jint typesLen = _env->GetArrayLength(_types);
- jlong *jTypesPtr = _env->GetLongArrayElements(_types, NULL);
+ jlong *jTypesPtr = _env->GetLongArrayElements(_types, nullptr);
RsType* typesPtr = (RsType*) malloc(sizeof(RsType) * typesLen);
for(int i = 0; i < typesLen; ++i) {
typesPtr[i] = (RsType)jTypesPtr[i];
@@ -1382,23 +1469,29 @@
static void
nScriptGroupSetInput(JNIEnv *_env, jobject _this, jlong con, jlong gid, jlong kid, jlong alloc)
{
- LOG_API("nScriptGroupSetInput, con(%p) group(%p), kernelId(%p), alloc(%p)", (RsContext)con,
- (void *)gid, (void *)kid, (void *)alloc);
+ if (kLogApi) {
+ ALOGD("nScriptGroupSetInput, con(%p) group(%p), kernelId(%p), alloc(%p)", (RsContext)con,
+ (void *)gid, (void *)kid, (void *)alloc);
+ }
rsScriptGroupSetInput((RsContext)con, (RsScriptGroup)gid, (RsScriptKernelID)kid, (RsAllocation)alloc);
}
static void
nScriptGroupSetOutput(JNIEnv *_env, jobject _this, jlong con, jlong gid, jlong kid, jlong alloc)
{
- LOG_API("nScriptGroupSetOutput, con(%p) group(%p), kernelId(%p), alloc(%p)", (RsContext)con,
- (void *)gid, (void *)kid, (void *)alloc);
+ if (kLogApi) {
+ ALOGD("nScriptGroupSetOutput, con(%p) group(%p), kernelId(%p), alloc(%p)", (RsContext)con,
+ (void *)gid, (void *)kid, (void *)alloc);
+ }
rsScriptGroupSetOutput((RsContext)con, (RsScriptGroup)gid, (RsScriptKernelID)kid, (RsAllocation)alloc);
}
static void
nScriptGroupExecute(JNIEnv *_env, jobject _this, jlong con, jlong gid)
{
- LOG_API("nScriptGroupSetOutput, con(%p) group(%p)", (RsContext)con, (void *)gid);
+ if (kLogApi) {
+ ALOGD("nScriptGroupSetOutput, con(%p) group(%p)", (RsContext)con, (void *)gid);
+ }
rsScriptGroupExecute((RsContext)con, (RsScriptGroup)gid);
}
@@ -1411,7 +1504,9 @@
jint srcFunc, jint destFunc,
jint depthFunc)
{
- LOG_API("nProgramStoreCreate, con(%p)", (RsContext)con);
+ if (kLogApi) {
+ ALOGD("nProgramStoreCreate, con(%p)", (RsContext)con);
+ }
return (jlong)(uintptr_t)rsProgramStoreCreate((RsContext)con, colorMaskR, colorMaskG, colorMaskB, colorMaskA,
depthMask, ditherEnable, (RsBlendSrcFunc)srcFunc,
(RsBlendDstFunc)destFunc, (RsDepthFunc)depthFunc);
@@ -1422,21 +1517,30 @@
static void
nProgramBindConstants(JNIEnv *_env, jobject _this, jlong con, jlong vpv, jint slot, jlong a)
{
- LOG_API("nProgramBindConstants, con(%p), vpf(%p), sloat(%i), a(%p)", (RsContext)con, (RsProgramVertex)vpv, slot, (RsAllocation)a);
+ if (kLogApi) {
+ ALOGD("nProgramBindConstants, con(%p), vpf(%p), sloat(%i), a(%p)", (RsContext)con,
+ (RsProgramVertex)vpv, slot, (RsAllocation)a);
+ }
rsProgramBindConstants((RsContext)con, (RsProgram)vpv, slot, (RsAllocation)a);
}
static void
nProgramBindTexture(JNIEnv *_env, jobject _this, jlong con, jlong vpf, jint slot, jlong a)
{
- LOG_API("nProgramBindTexture, con(%p), vpf(%p), slot(%i), a(%p)", (RsContext)con, (RsProgramFragment)vpf, slot, (RsAllocation)a);
+ if (kLogApi) {
+ ALOGD("nProgramBindTexture, con(%p), vpf(%p), slot(%i), a(%p)", (RsContext)con,
+ (RsProgramFragment)vpf, slot, (RsAllocation)a);
+ }
rsProgramBindTexture((RsContext)con, (RsProgramFragment)vpf, slot, (RsAllocation)a);
}
static void
nProgramBindSampler(JNIEnv *_env, jobject _this, jlong con, jlong vpf, jint slot, jlong a)
{
- LOG_API("nProgramBindSampler, con(%p), vpf(%p), slot(%i), a(%p)", (RsContext)con, (RsProgramFragment)vpf, slot, (RsSampler)a);
+ if (kLogApi) {
+ ALOGD("nProgramBindSampler, con(%p), vpf(%p), slot(%i), a(%p)", (RsContext)con,
+ (RsProgramFragment)vpf, slot, (RsSampler)a);
+ }
rsProgramBindSampler((RsContext)con, (RsProgramFragment)vpf, slot, (RsSampler)a);
}
@@ -1447,7 +1551,7 @@
jobjectArray texNames, jlongArray params)
{
AutoJavaStringToUTF8 shaderUTF(_env, shader);
- jlong *jParamPtr = _env->GetLongArrayElements(params, NULL);
+ jlong *jParamPtr = _env->GetLongArrayElements(params, nullptr);
jint paramLen = _env->GetArrayLength(params);
int texCount = _env->GetArrayLength(texNames);
@@ -1455,7 +1559,9 @@
const char ** nameArray = names.c_str();
size_t* sizeArray = names.c_str_len();
- LOG_API("nProgramFragmentCreate, con(%p), paramLen(%i)", (RsContext)con, paramLen);
+ if (kLogApi) {
+ ALOGD("nProgramFragmentCreate, con(%p), paramLen(%i)", (RsContext)con, paramLen);
+ }
uintptr_t * paramPtr = (uintptr_t*) malloc(sizeof(uintptr_t) * paramLen);
for(int i = 0; i < paramLen; ++i) {
@@ -1478,10 +1584,12 @@
jobjectArray texNames, jlongArray params)
{
AutoJavaStringToUTF8 shaderUTF(_env, shader);
- jlong *jParamPtr = _env->GetLongArrayElements(params, NULL);
+ jlong *jParamPtr = _env->GetLongArrayElements(params, nullptr);
jint paramLen = _env->GetArrayLength(params);
- LOG_API("nProgramVertexCreate, con(%p), paramLen(%i)", (RsContext)con, paramLen);
+ if (kLogApi) {
+ ALOGD("nProgramVertexCreate, con(%p), paramLen(%i)", (RsContext)con, paramLen);
+ }
int texCount = _env->GetArrayLength(texNames);
AutoJavaStringArrayToUTF8 names(_env, texNames, texCount);
@@ -1507,7 +1615,10 @@
static jlong
nProgramRasterCreate(JNIEnv *_env, jobject _this, jlong con, jboolean pointSprite, jint cull)
{
- LOG_API("nProgramRasterCreate, con(%p), pointSprite(%i), cull(%i)", (RsContext)con, pointSprite, cull);
+ if (kLogApi) {
+ ALOGD("nProgramRasterCreate, con(%p), pointSprite(%i), cull(%i)", (RsContext)con,
+ pointSprite, cull);
+ }
return (jlong)(uintptr_t)rsProgramRasterCreate((RsContext)con, pointSprite, (RsCullMode)cull);
}
@@ -1517,35 +1628,46 @@
static void
nContextBindRootScript(JNIEnv *_env, jobject _this, jlong con, jlong script)
{
- LOG_API("nContextBindRootScript, con(%p), script(%p)", (RsContext)con, (RsScript)script);
+ if (kLogApi) {
+ ALOGD("nContextBindRootScript, con(%p), script(%p)", (RsContext)con, (RsScript)script);
+ }
rsContextBindRootScript((RsContext)con, (RsScript)script);
}
static void
nContextBindProgramStore(JNIEnv *_env, jobject _this, jlong con, jlong pfs)
{
- LOG_API("nContextBindProgramStore, con(%p), pfs(%p)", (RsContext)con, (RsProgramStore)pfs);
+ if (kLogApi) {
+ ALOGD("nContextBindProgramStore, con(%p), pfs(%p)", (RsContext)con, (RsProgramStore)pfs);
+ }
rsContextBindProgramStore((RsContext)con, (RsProgramStore)pfs);
}
static void
nContextBindProgramFragment(JNIEnv *_env, jobject _this, jlong con, jlong pf)
{
- LOG_API("nContextBindProgramFragment, con(%p), pf(%p)", (RsContext)con, (RsProgramFragment)pf);
+ if (kLogApi) {
+ ALOGD("nContextBindProgramFragment, con(%p), pf(%p)", (RsContext)con,
+ (RsProgramFragment)pf);
+ }
rsContextBindProgramFragment((RsContext)con, (RsProgramFragment)pf);
}
static void
nContextBindProgramVertex(JNIEnv *_env, jobject _this, jlong con, jlong pf)
{
- LOG_API("nContextBindProgramVertex, con(%p), pf(%p)", (RsContext)con, (RsProgramVertex)pf);
+ if (kLogApi) {
+ ALOGD("nContextBindProgramVertex, con(%p), pf(%p)", (RsContext)con, (RsProgramVertex)pf);
+ }
rsContextBindProgramVertex((RsContext)con, (RsProgramVertex)pf);
}
static void
nContextBindProgramRaster(JNIEnv *_env, jobject _this, jlong con, jlong pf)
{
- LOG_API("nContextBindProgramRaster, con(%p), pf(%p)", (RsContext)con, (RsProgramRaster)pf);
+ if (kLogApi) {
+ ALOGD("nContextBindProgramRaster, con(%p), pf(%p)", (RsContext)con, (RsProgramRaster)pf);
+ }
rsContextBindProgramRaster((RsContext)con, (RsProgramRaster)pf);
}
@@ -1556,7 +1678,9 @@
nSamplerCreate(JNIEnv *_env, jobject _this, jlong con, jint magFilter, jint minFilter,
jint wrapS, jint wrapT, jint wrapR, jfloat aniso)
{
- LOG_API("nSamplerCreate, con(%p)", (RsContext)con);
+ if (kLogApi) {
+ ALOGD("nSamplerCreate, con(%p)", (RsContext)con);
+ }
return (jlong)(uintptr_t)rsSamplerCreate((RsContext)con,
(RsSamplerValue)magFilter,
(RsSamplerValue)minFilter,
@@ -1570,7 +1694,9 @@
static jlong
nPathCreate(JNIEnv *_env, jobject _this, jlong con, jint prim, jboolean isStatic, jlong _vtx, jlong _loop, jfloat q) {
- LOG_API("nPathCreate, con(%p)", (RsContext)con);
+ if (kLogApi) {
+ ALOGD("nPathCreate, con(%p)", (RsContext)con);
+ }
jlong id = (jlong)(uintptr_t)rsPathCreate((RsContext)con, (RsPathPrimitive)prim, isStatic,
(RsAllocation)_vtx,
@@ -1581,24 +1707,26 @@
static jlong
nMeshCreate(JNIEnv *_env, jobject _this, jlong con, jlongArray _vtx, jlongArray _idx, jintArray _prim)
{
- LOG_API("nMeshCreate, con(%p)", (RsContext)con);
+ if (kLogApi) {
+ ALOGD("nMeshCreate, con(%p)", (RsContext)con);
+ }
jint vtxLen = _env->GetArrayLength(_vtx);
- jlong *jVtxPtr = _env->GetLongArrayElements(_vtx, NULL);
+ jlong *jVtxPtr = _env->GetLongArrayElements(_vtx, nullptr);
RsAllocation* vtxPtr = (RsAllocation*) malloc(sizeof(RsAllocation) * vtxLen);
for(int i = 0; i < vtxLen; ++i) {
vtxPtr[i] = (RsAllocation)(uintptr_t)jVtxPtr[i];
}
jint idxLen = _env->GetArrayLength(_idx);
- jlong *jIdxPtr = _env->GetLongArrayElements(_idx, NULL);
+ jlong *jIdxPtr = _env->GetLongArrayElements(_idx, nullptr);
RsAllocation* idxPtr = (RsAllocation*) malloc(sizeof(RsAllocation) * idxLen);
for(int i = 0; i < idxLen; ++i) {
idxPtr[i] = (RsAllocation)(uintptr_t)jIdxPtr[i];
}
jint primLen = _env->GetArrayLength(_prim);
- jint *primPtr = _env->GetIntArrayElements(_prim, NULL);
+ jint *primPtr = _env->GetIntArrayElements(_prim, nullptr);
jlong id = (jlong)(uintptr_t)rsMeshCreate((RsContext)con,
(RsAllocation *)vtxPtr, vtxLen,
@@ -1616,7 +1744,9 @@
static jint
nMeshGetVertexBufferCount(JNIEnv *_env, jobject _this, jlong con, jlong mesh)
{
- LOG_API("nMeshGetVertexBufferCount, con(%p), Mesh(%p)", (RsContext)con, (RsMesh)mesh);
+ if (kLogApi) {
+ ALOGD("nMeshGetVertexBufferCount, con(%p), Mesh(%p)", (RsContext)con, (RsMesh)mesh);
+ }
jint vtxCount = 0;
rsaMeshGetVertexBufferCount((RsContext)con, (RsMesh)mesh, &vtxCount);
return vtxCount;
@@ -1625,7 +1755,9 @@
static jint
nMeshGetIndexCount(JNIEnv *_env, jobject _this, jlong con, jlong mesh)
{
- LOG_API("nMeshGetIndexCount, con(%p), Mesh(%p)", (RsContext)con, (RsMesh)mesh);
+ if (kLogApi) {
+ ALOGD("nMeshGetIndexCount, con(%p), Mesh(%p)", (RsContext)con, (RsMesh)mesh);
+ }
jint idxCount = 0;
rsaMeshGetIndexCount((RsContext)con, (RsMesh)mesh, &idxCount);
return idxCount;
@@ -1634,7 +1766,9 @@
static void
nMeshGetVertices(JNIEnv *_env, jobject _this, jlong con, jlong mesh, jlongArray _ids, jint numVtxIDs)
{
- LOG_API("nMeshGetVertices, con(%p), Mesh(%p)", (RsContext)con, (RsMesh)mesh);
+ if (kLogApi) {
+ ALOGD("nMeshGetVertices, con(%p), Mesh(%p)", (RsContext)con, (RsMesh)mesh);
+ }
RsAllocation *allocs = (RsAllocation*)malloc((uint32_t)numVtxIDs * sizeof(RsAllocation));
rsaMeshGetVertices((RsContext)con, (RsMesh)mesh, allocs, (uint32_t)numVtxIDs);
@@ -1650,7 +1784,9 @@
static void
nMeshGetIndices(JNIEnv *_env, jobject _this, jlong con, jlong mesh, jlongArray _idxIds, jintArray _primitives, jint numIndices)
{
- LOG_API("nMeshGetVertices, con(%p), Mesh(%p)", (RsContext)con, (RsMesh)mesh);
+ if (kLogApi) {
+ ALOGD("nMeshGetVertices, con(%p), Mesh(%p)", (RsContext)con, (RsMesh)mesh);
+ }
RsAllocation *allocs = (RsAllocation*)malloc((uint32_t)numIndices * sizeof(RsAllocation));
uint32_t *prims= (uint32_t*)malloc((uint32_t)numIndices * sizeof(uint32_t));
@@ -1757,12 +1893,9 @@
{"rsnScriptSetTimeZone", "(JJ[B)V", (void*)nScriptSetTimeZone },
{"rsnScriptInvoke", "(JJI)V", (void*)nScriptInvoke },
{"rsnScriptInvokeV", "(JJI[B)V", (void*)nScriptInvokeV },
-{"rsnScriptForEach", "(JJIJJ)V", (void*)nScriptForEach },
-{"rsnScriptForEach", "(JJIJJ[B)V", (void*)nScriptForEachV },
-{"rsnScriptForEachClipped", "(JJIJJIIIIII)V", (void*)nScriptForEachClipped },
-{"rsnScriptForEachClipped", "(JJIJJ[BIIIIII)V", (void*)nScriptForEachClippedV },
-{"rsnScriptForEachMultiClipped", "(JJI[JJIIIIII)V", (void*)nScriptForEachMultiClipped },
-{"rsnScriptForEachMultiClipped", "(JJI[JJ[BIIIIII)V", (void*)nScriptForEachMultiClippedV },
+
+{"rsnScriptForEach", "(JJI[JJ[B[I)V", (void*)nScriptForEach },
+
{"rsnScriptSetVarI", "(JJII)V", (void*)nScriptSetVarI },
{"rsnScriptGetVarI", "(JJI)I", (void*)nScriptGetVarI },
{"rsnScriptSetVarJ", "(JJIJ)V", (void*)nScriptSetVarJ },
@@ -1824,14 +1957,14 @@
jint JNI_OnLoad(JavaVM* vm, void* reserved)
{
- JNIEnv* env = NULL;
+ JNIEnv* env = nullptr;
jint result = -1;
if (vm->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) {
ALOGE("ERROR: GetEnv failed\n");
goto bail;
}
- assert(env != NULL);
+ assert(env != nullptr);
if (registerFuncs(env) < 0) {
ALOGE("ERROR: Renderscript native registration failed\n");
diff --git a/services/Android.mk b/services/Android.mk
index 3c94f43..da85528 100644
--- a/services/Android.mk
+++ b/services/Android.mk
@@ -48,10 +48,6 @@
LOCAL_CFLAGS += -DEGL_EGLEXT_PROTOTYPES -DGL_GLEXT_PROTOTYPES
-ifeq ($(WITH_MALLOC_LEAK_CHECK),true)
- LOCAL_CFLAGS += -DMALLOC_LEAK_CHECK
-endif
-
LOCAL_MODULE:= libandroid_servers
include $(BUILD_SHARED_LIBRARY)
diff --git a/services/accessibility/java/com/android/server/accessibility/GestureUtils.java b/services/accessibility/java/com/android/server/accessibility/GestureUtils.java
index b68b09f..bc76191 100644
--- a/services/accessibility/java/com/android/server/accessibility/GestureUtils.java
+++ b/services/accessibility/java/com/android/server/accessibility/GestureUtils.java
@@ -69,8 +69,7 @@
return true;
}
- final float firstMagnitude =
- (float) Math.sqrt(firstDeltaX * firstDeltaX + firstDeltaY * firstDeltaY);
+ final float firstMagnitude = (float) Math.hypot(firstDeltaX, firstDeltaY);
final float firstXNormalized =
(firstMagnitude > 0) ? firstDeltaX / firstMagnitude : firstDeltaX;
final float firstYNormalized =
@@ -83,8 +82,7 @@
return true;
}
- final float secondMagnitude =
- (float) Math.sqrt(secondDeltaX * secondDeltaX + secondDeltaY * secondDeltaY);
+ final float secondMagnitude = (float) Math.hypot(secondDeltaX, secondDeltaY);
final float secondXNormalized =
(secondMagnitude > 0) ? secondDeltaX / secondMagnitude : secondDeltaX;
final float secondYNormalized =
diff --git a/services/core/java/com/android/server/LockSettingsStorage.java b/services/core/java/com/android/server/LockSettingsStorage.java
index e92ea72d..c03bb58 100644
--- a/services/core/java/com/android/server/LockSettingsStorage.java
+++ b/services/core/java/com/android/server/LockSettingsStorage.java
@@ -16,6 +16,8 @@
package com.android.server;
+import com.android.internal.annotations.VisibleForTesting;
+
import android.content.ContentValues;
import android.content.Context;
import android.content.pm.UserInfo;
@@ -243,11 +245,13 @@
}
- private String getLockPatternFilename(int userId) {
+ @VisibleForTesting
+ String getLockPatternFilename(int userId) {
return getLockCredentialFilePathForUser(userId, LOCK_PATTERN_FILE);
}
- private String getLockPasswordFilename(int userId) {
+ @VisibleForTesting
+ String getLockPasswordFilename(int userId) {
return getLockCredentialFilePathForUser(userId, LOCK_PASSWORD_FILE);
}
@@ -310,6 +314,15 @@
}
}
+ @VisibleForTesting
+ void closeDatabase() {
+ mOpenHelper.close();
+ }
+
+ @VisibleForTesting
+ void clearCache() {
+ mCache.clear();
+ }
public interface Callback {
void initialize(SQLiteDatabase db);
@@ -455,6 +468,10 @@
mVersion++;
}
+ synchronized void clear() {
+ mCache.clear();
+ mVersion++;
+ }
private static final class CacheKey {
static final int TYPE_KEY_VALUE = 0;
diff --git a/services/core/java/com/android/server/NativeDaemonConnector.java b/services/core/java/com/android/server/NativeDaemonConnector.java
index 8c3b020..96f9ab0 100644
--- a/services/core/java/com/android/server/NativeDaemonConnector.java
+++ b/services/core/java/com/android/server/NativeDaemonConnector.java
@@ -176,6 +176,7 @@
if (buffer[i] == 0) {
final String rawEvent = new String(
buffer, start, i - start, StandardCharsets.UTF_8);
+ log("RCV <- {" + rawEvent + "}");
boolean releaseWl = false;
try {
@@ -196,6 +197,7 @@
mResponseQueue.add(event.getCmdNumber(), event);
}
} catch (IllegalArgumentException e) {
+ log("Problem parsing message: " + rawEvent + " - " + e);
} finally {
if (releaseWl) {
mWakeLock.acquire();
@@ -207,6 +209,7 @@
}
if (start == 0) {
final String rawEvent = new String(buffer, start, count, StandardCharsets.UTF_8);
+ log("RCV incomplete <- {" + rawEvent + "}");
}
// We should end at the amount we read. If not, compact then
diff --git a/services/core/java/com/android/server/TelephonyRegistry.java b/services/core/java/com/android/server/TelephonyRegistry.java
index ba93213..2ed021a 100644
--- a/services/core/java/com/android/server/TelephonyRegistry.java
+++ b/services/core/java/com/android/server/TelephonyRegistry.java
@@ -34,6 +34,8 @@
import android.telephony.CellLocation;
import android.telephony.DataConnectionRealTimeInfo;
import android.telephony.Rlog;
+import android.telephony.SubscriptionInfo;
+import android.telephony.SubscriptionListener;
import android.telephony.TelephonyManager;
import android.telephony.SubscriptionManager;
import android.telephony.PhoneStateListener;
@@ -56,6 +58,7 @@
import java.io.PrintWriter;
import com.android.internal.app.IBatteryStats;
+import com.android.internal.telephony.ISubscriptionListener;
import com.android.internal.telephony.ITelephonyRegistry;
import com.android.internal.telephony.IPhoneStateListener;
import com.android.internal.telephony.DefaultPhoneNotifier;
@@ -90,19 +93,30 @@
IBinder binder;
IPhoneStateListener callback;
+ ISubscriptionListener subscriptionListenerCallback;
int callerUid;
int events;
- int subId;
+ int subId = SubscriptionManager.INVALID_SUB_ID;
- int phoneId;
+ int phoneId = SubscriptionManager.INVALID_PHONE_ID;
+
+ boolean matchPhoneStateListenerEvent(int events) {
+ return (callback != null) && ((events & this.events) != 0);
+ }
+
+ boolean matchSubscriptionListenerEvent(int events) {
+ return (subscriptionListenerCallback != null) && ((events & this.events) != 0);
+ }
@Override
public String toString() {
- return "{pkgForDebug=" + pkgForDebug + " callerUid=" + callerUid + " subId=" + subId +
- " phoneId=" + phoneId + " events=" + Integer.toHexString(events) + "}";
+ return "{pkgForDebug=" + pkgForDebug + " binder=" + binder + " callback=" + callback
+ + " subscriptionListenererCallback=" + subscriptionListenerCallback
+ + " callerUid=" + callerUid + " subId=" + subId + " phoneId=" + phoneId
+ + " events=" + Integer.toHexString(events) + "}";
}
}
@@ -325,6 +339,101 @@
}
@Override
+ public void registerSubscriptionListener(String pkgForDebug, ISubscriptionListener callback,
+ int events) {
+ int callerUid = UserHandle.getCallingUserId();
+ int myUid = UserHandle.myUserId();
+ if (VDBG) {
+ log("listen sl: E pkg=" + pkgForDebug + " events=0x" + Integer.toHexString(events)
+ + " myUid=" + myUid + " callerUid=" + callerUid + " callback=" + callback
+ + " callback.asBinder=" + callback.asBinder());
+ }
+
+ if (events != 0) {
+ /* Checks permission and throws Security exception */
+ checkSubscriptionListenerPermission(events);
+ Record r = null;
+
+ synchronized (mRecords) {
+ // register
+ find_and_add: {
+ IBinder b = callback.asBinder();
+ final int N = mRecords.size();
+ for (int i = 0; i < N; i++) {
+ r = mRecords.get(i);
+ if (b == r.binder) {
+ break find_and_add;
+ }
+ }
+ r = new Record();
+ r.binder = b;
+ mRecords.add(r);
+ if (DBG) log("listen sl: add new record");
+ }
+
+ r.subscriptionListenerCallback = callback;
+ r.pkgForDebug = pkgForDebug;
+ r.callerUid = callerUid;
+ r.events = events;
+ if (DBG) {
+ log("listen sl: Register r=" + r);
+ }
+ }
+
+ // Always notify when a listen is established.
+ if (r.matchSubscriptionListenerEvent(
+ SubscriptionListener.LISTEN_SUBSCRIPTION_INFO_LIST_CHANGED)) {
+ try {
+ if (VDBG) log("listen sl: send to r=" + r);
+ r.subscriptionListenerCallback.onSubscriptionInfoChanged();
+ if (VDBG) log("listen sl: sent to r=" + r);
+ } catch (RemoteException e) {
+ if (VDBG) log("listen sl: remote exception sending to r=" + r + " e=" + e);
+ remove(r.binder);
+ }
+ }
+ } else {
+ if (DBG) log("listen sl: Unregister as event is LISTEN_NONE");
+ unregisterSubscriptionListener(pkgForDebug, callback);
+ }
+ }
+
+ @Override
+ public void unregisterSubscriptionListener(String pkgForDebug, ISubscriptionListener callback) {
+ if (DBG) log("listen sl: Unregister as event is LISTEN_NONE");
+ remove(callback.asBinder());
+ }
+
+ private void checkSubscriptionListenerPermission(int events) {
+ if ((events & SubscriptionListener.LISTEN_SUBSCRIPTION_INFO_LIST_CHANGED) != 0) {
+ mContext.enforceCallingOrSelfPermission(
+ SubscriptionListener.PERMISSION_LISTEN_SUBSCRIPTION_INFO_LIST_CHANGED, null);
+ }
+ }
+
+ @Override
+ public void notifySubscriptionInfoChanged() {
+ if (VDBG) log("notifySubscriptionInfoChanged:");
+ synchronized (mRecords) {
+ mRemoveList.clear();
+ for (Record r : mRecords) {
+ if (r.matchSubscriptionListenerEvent(
+ SubscriptionListener.LISTEN_SUBSCRIPTION_INFO_LIST_CHANGED)) {
+ try {
+ if (VDBG) log("notifySubscriptionInfoChanged: send to r=" + r);
+ r.subscriptionListenerCallback.onSubscriptionInfoChanged();
+ if (VDBG) log("notifySubscriptionInfoChanged: sent to r=" + r);
+ } catch (RemoteException ex) {
+ if (VDBG) log("notifySubscriptionInfoChanged: RemoteException r=" + r);
+ mRemoveList.add(r.binder);
+ }
+ }
+ }
+ handleRemoveListLocked();
+ }
+ }
+
+ @Override
public void listen(String pkgForDebug, IPhoneStateListener callback, int events,
boolean notifyNow) {
listenForSubscriber(SubscriptionManager.DEFAULT_SUB_ID, pkgForDebug, callback, events,
@@ -513,6 +622,7 @@
final int recordCount = mRecords.size();
for (int i = 0; i < recordCount; i++) {
if (mRecords.get(i).binder == binder) {
+ if (VDBG) log("remove: binder=" + binder);
mRecords.remove(i);
return;
}
@@ -531,7 +641,7 @@
synchronized (mRecords) {
for (Record r : mRecords) {
- if (((r.events & PhoneStateListener.LISTEN_CALL_STATE) != 0) &&
+ if (r.matchPhoneStateListenerEvent(PhoneStateListener.LISTEN_CALL_STATE) &&
(r.subId == SubscriptionManager.DEFAULT_SUB_ID)) {
try {
r.callback.onCallStateChanged(state, incomingNumber);
@@ -559,7 +669,7 @@
mCallState[phoneId] = state;
mCallIncomingNumber[phoneId] = incomingNumber;
for (Record r : mRecords) {
- if (((r.events & PhoneStateListener.LISTEN_CALL_STATE) != 0) &&
+ if (r.matchPhoneStateListenerEvent(PhoneStateListener.LISTEN_CALL_STATE) &&
(r.subId == subId) &&
(r.subId != SubscriptionManager.DEFAULT_SUB_ID)) {
try {
@@ -595,7 +705,7 @@
log("notifyServiceStateForSubscriber: r=" + r + " subId=" + subId
+ " phoneId=" + phoneId + " state=" + state);
}
- if (((r.events & PhoneStateListener.LISTEN_SERVICE_STATE) != 0) &&
+ if (r.matchPhoneStateListenerEvent(PhoneStateListener.LISTEN_SERVICE_STATE) &&
idMatch(r.subId, subId, phoneId)) {
try {
if (DBG) {
@@ -640,7 +750,8 @@
log("notifySignalStrengthForSubscriber: r=" + r + " subId=" + subId
+ " phoneId=" + phoneId + " ss=" + signalStrength);
}
- if (((r.events & PhoneStateListener.LISTEN_SIGNAL_STRENGTHS) != 0) &&
+ if (r.matchPhoneStateListenerEvent(
+ PhoneStateListener.LISTEN_SIGNAL_STRENGTHS) &&
idMatch(r.subId, subId, phoneId)) {
try {
if (DBG) {
@@ -653,7 +764,7 @@
mRemoveList.add(r.binder);
}
}
- if (((r.events & PhoneStateListener.LISTEN_SIGNAL_STRENGTH) != 0) &&
+ if (r.matchPhoneStateListenerEvent(PhoneStateListener.LISTEN_SIGNAL_STRENGTH) &&
idMatch(r.subId, subId, phoneId)){
try {
int gsmSignalStrength = signalStrength.getGsmSignalStrength();
@@ -750,7 +861,8 @@
if (validatePhoneId(phoneId)) {
mMessageWaiting[phoneId] = mwi;
for (Record r : mRecords) {
- if (((r.events & PhoneStateListener.LISTEN_MESSAGE_WAITING_INDICATOR) != 0) &&
+ if (r.matchPhoneStateListenerEvent(
+ PhoneStateListener.LISTEN_MESSAGE_WAITING_INDICATOR) &&
idMatch(r.subId, subId, phoneId)) {
try {
r.callback.onMessageWaitingIndicatorChanged(mwi);
@@ -781,7 +893,8 @@
if (validatePhoneId(phoneId)) {
mCallForwarding[phoneId] = cfi;
for (Record r : mRecords) {
- if (((r.events & PhoneStateListener.LISTEN_CALL_FORWARDING_INDICATOR) != 0) &&
+ if (r.matchPhoneStateListenerEvent(
+ PhoneStateListener.LISTEN_CALL_FORWARDING_INDICATOR) &&
idMatch(r.subId, subId, phoneId)) {
try {
r.callback.onCallForwardingIndicatorChanged(cfi);
@@ -807,7 +920,7 @@
int phoneId = SubscriptionManager.getPhoneId(subId);
mDataActivity[phoneId] = state;
for (Record r : mRecords) {
- if ((r.events & PhoneStateListener.LISTEN_DATA_ACTIVITY) != 0) {
+ if (r.matchPhoneStateListenerEvent(PhoneStateListener.LISTEN_DATA_ACTIVITY)) {
try {
r.callback.onDataActivity(state);
} catch (RemoteException ex) {
@@ -878,7 +991,8 @@
+ ", " + mDataConnectionNetworkType[phoneId] + ")");
}
for (Record r : mRecords) {
- if (((r.events & PhoneStateListener.LISTEN_DATA_CONNECTION_STATE) != 0) &&
+ if (r.matchPhoneStateListenerEvent(
+ PhoneStateListener.LISTEN_DATA_CONNECTION_STATE) &&
idMatch(r.subId, subId, phoneId)) {
try {
log("Notify data connection state changed on sub: " +
@@ -895,7 +1009,8 @@
mPreciseDataConnectionState = new PreciseDataConnectionState(state, networkType,
apnType, apn, reason, linkProperties, "");
for (Record r : mRecords) {
- if ((r.events & PhoneStateListener.LISTEN_PRECISE_DATA_CONNECTION_STATE) != 0) {
+ if (r.matchPhoneStateListenerEvent(
+ PhoneStateListener.LISTEN_PRECISE_DATA_CONNECTION_STATE)) {
try {
r.callback.onPreciseDataConnectionStateChanged(mPreciseDataConnectionState);
} catch (RemoteException ex) {
@@ -930,7 +1045,8 @@
TelephonyManager.DATA_UNKNOWN,TelephonyManager.NETWORK_TYPE_UNKNOWN,
apnType, "", reason, null, "");
for (Record r : mRecords) {
- if ((r.events & PhoneStateListener.LISTEN_PRECISE_DATA_CONNECTION_STATE) != 0) {
+ if (r.matchPhoneStateListenerEvent(
+ PhoneStateListener.LISTEN_PRECISE_DATA_CONNECTION_STATE)) {
try {
r.callback.onPreciseDataConnectionStateChanged(mPreciseDataConnectionState);
} catch (RemoteException ex) {
@@ -989,7 +1105,7 @@
synchronized (mRecords) {
mOtaspMode = otaspMode;
for (Record r : mRecords) {
- if ((r.events & PhoneStateListener.LISTEN_OTASP_CHANGED) != 0) {
+ if (r.matchPhoneStateListenerEvent(PhoneStateListener.LISTEN_OTASP_CHANGED)) {
try {
r.callback.onOtaspChanged(otaspMode);
} catch (RemoteException ex) {
@@ -1015,7 +1131,7 @@
DisconnectCause.NOT_VALID,
PreciseDisconnectCause.NOT_VALID);
for (Record r : mRecords) {
- if ((r.events & PhoneStateListener.LISTEN_PRECISE_CALL_STATE) != 0) {
+ if (r.matchPhoneStateListenerEvent(PhoneStateListener.LISTEN_PRECISE_CALL_STATE)) {
try {
r.callback.onPreciseCallStateChanged(mPreciseCallState);
} catch (RemoteException ex) {
@@ -1038,7 +1154,7 @@
mPreciseCallState = new PreciseCallState(mRingingCallState, mForegroundCallState,
mBackgroundCallState, disconnectCause, preciseDisconnectCause);
for (Record r : mRecords) {
- if ((r.events & PhoneStateListener.LISTEN_PRECISE_CALL_STATE) != 0) {
+ if (r.matchPhoneStateListenerEvent(PhoneStateListener.LISTEN_PRECISE_CALL_STATE)) {
try {
r.callback.onPreciseCallStateChanged(mPreciseCallState);
} catch (RemoteException ex) {
@@ -1062,7 +1178,8 @@
TelephonyManager.DATA_UNKNOWN, TelephonyManager.NETWORK_TYPE_UNKNOWN,
apnType, apn, reason, null, failCause);
for (Record r : mRecords) {
- if ((r.events & PhoneStateListener.LISTEN_PRECISE_DATA_CONNECTION_STATE) != 0) {
+ if (r.matchPhoneStateListenerEvent(
+ PhoneStateListener.LISTEN_PRECISE_DATA_CONNECTION_STATE)) {
try {
r.callback.onPreciseDataConnectionStateChanged(mPreciseDataConnectionState);
} catch (RemoteException ex) {
@@ -1083,7 +1200,7 @@
synchronized (mRecords) {
mVoLteServiceState = lteState;
for (Record r : mRecords) {
- if ((r.events & PhoneStateListener.LISTEN_VOLTE_STATE) != 0) {
+ if (r.matchPhoneStateListenerEvent(PhoneStateListener.LISTEN_VOLTE_STATE)) {
try {
r.callback.onVoLteServiceStateChanged(
new VoLteServiceState(mVoLteServiceState));
@@ -1106,7 +1223,8 @@
if (VDBG) {
log("notifyOemHookRawEventForSubscriber: r=" + r + " subId=" + subId);
}
- if (((r.events & PhoneStateListener.LISTEN_OEM_HOOK_RAW_EVENT) != 0) &&
+ if ((r.matchPhoneStateListenerEvent(
+ PhoneStateListener.LISTEN_OEM_HOOK_RAW_EVENT)) &&
((r.subId == subId) ||
(r.subId == SubscriptionManager.DEFAULT_SUB_ID))) {
try {
@@ -1337,7 +1455,9 @@
}
private void handleRemoveListLocked() {
- if (mRemoveList.size() > 0) {
+ int size = mRemoveList.size();
+ if (VDBG) log("handleRemoveListLocked: mRemoveList.size()=" + size);
+ if (size > 0) {
for (IBinder b: mRemoveList) {
remove(b);
}
@@ -1351,7 +1471,7 @@
boolean valid = false;
try {
foregroundUser = ActivityManager.getCurrentUser();
- valid = r.callerUid == foregroundUser && (r.events & events) != 0;
+ valid = r.callerUid == foregroundUser && r.matchPhoneStateListenerEvent(events);
if (DBG | DBG_LOC) {
log("validateEventsAndUserLocked: valid=" + valid
+ " r.callerUid=" + r.callerUid + " foregroundUser=" + foregroundUser
diff --git a/services/core/java/com/android/server/TwilightCalculator.java b/services/core/java/com/android/server/TwilightCalculator.java
index a5c93b5..5839b16 100644
--- a/services/core/java/com/android/server/TwilightCalculator.java
+++ b/services/core/java/com/android/server/TwilightCalculator.java
@@ -17,7 +17,6 @@
package com.android.server;
import android.text.format.DateUtils;
-import android.util.FloatMath;
/** @hide */
public class TwilightCalculator {
@@ -75,24 +74,24 @@
final float meanAnomaly = 6.240059968f + daysSince2000 * 0.01720197f;
// true anomaly
- final float trueAnomaly = meanAnomaly + C1 * FloatMath.sin(meanAnomaly) + C2
- * FloatMath.sin(2 * meanAnomaly) + C3 * FloatMath.sin(3 * meanAnomaly);
+ final double trueAnomaly = meanAnomaly + C1 * Math.sin(meanAnomaly) + C2
+ * Math.sin(2 * meanAnomaly) + C3 * Math.sin(3 * meanAnomaly);
// ecliptic longitude
- final float solarLng = trueAnomaly + 1.796593063f + (float) Math.PI;
+ final double solarLng = trueAnomaly + 1.796593063d + Math.PI;
// solar transit in days since 2000
final double arcLongitude = -longitude / 360;
float n = Math.round(daysSince2000 - J0 - arcLongitude);
- double solarTransitJ2000 = n + J0 + arcLongitude + 0.0053f * FloatMath.sin(meanAnomaly)
- + -0.0069f * FloatMath.sin(2 * solarLng);
+ double solarTransitJ2000 = n + J0 + arcLongitude + 0.0053d * Math.sin(meanAnomaly)
+ + -0.0069d * Math.sin(2 * solarLng);
// declination of sun
- double solarDec = Math.asin(FloatMath.sin(solarLng) * FloatMath.sin(OBLIQUITY));
+ double solarDec = Math.asin(Math.sin(solarLng) * Math.sin(OBLIQUITY));
final double latRad = latiude * DEGREES_TO_RADIANS;
- double cosHourAngle = (FloatMath.sin(ALTIDUTE_CORRECTION_CIVIL_TWILIGHT) - Math.sin(latRad)
+ double cosHourAngle = (Math.sin(ALTIDUTE_CORRECTION_CIVIL_TWILIGHT) - Math.sin(latRad)
* Math.sin(solarDec)) / (Math.cos(latRad) * Math.cos(solarDec));
// The day or night never ends for the given date and location, if this value is out of
// range.
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 1cf96c3..682642e 100755
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -8160,6 +8160,16 @@
}
}
+ private TaskRecord taskForIdLocked(int id) {
+ final TaskRecord task = recentTaskForIdLocked(id);
+ if (task != null) {
+ return task;
+ }
+
+ // Don't give up. Sometimes it just hasn't made it to recents yet.
+ return mStackSupervisor.anyTaskForIdLocked(id);
+ }
+
private TaskRecord recentTaskForIdLocked(int id) {
final int N = mRecentTasks.size();
for (int i=0; i<N; i++) {
@@ -8380,7 +8390,7 @@
* @return Returns true if the given task was found and removed.
*/
private boolean removeTaskByIdLocked(int taskId, boolean killProcess) {
- TaskRecord tr = recentTaskForIdLocked(taskId);
+ TaskRecord tr = taskForIdLocked(taskId);
if (tr != null) {
tr.removeTaskActivitiesLocked();
cleanUpRemovedTaskLocked(tr, killProcess);
@@ -8455,7 +8465,7 @@
"moveTaskToBack()");
synchronized(this) {
- TaskRecord tr = recentTaskForIdLocked(taskId);
+ TaskRecord tr = taskForIdLocked(taskId);
if (tr != null) {
if (tr == mStackSupervisor.mLockTaskModeTask) {
mStackSupervisor.showLockTaskToast();
@@ -8647,7 +8657,7 @@
long ident = Binder.clearCallingIdentity();
try {
synchronized (this) {
- TaskRecord tr = recentTaskForIdLocked(taskId);
+ TaskRecord tr = taskForIdLocked(taskId);
return tr != null && tr.stack != null && tr.stack.isHomeStack();
}
} finally {
diff --git a/services/core/java/com/android/server/am/ActivityRecord.java b/services/core/java/com/android/server/am/ActivityRecord.java
index 1a0e45e..c12cadb 100755
--- a/services/core/java/com/android/server/am/ActivityRecord.java
+++ b/services/core/java/com/android/server/am/ActivityRecord.java
@@ -21,6 +21,7 @@
import android.os.Trace;
import com.android.internal.app.ResolverActivity;
+import com.android.internal.content.ReferrerIntent;
import com.android.internal.util.XmlUtils;
import com.android.server.AttributeCache;
import com.android.server.am.ActivityStack.ActivityState;
@@ -128,7 +129,7 @@
final int requestCode; // code given by requester (resultTo)
ArrayList<ResultInfo> results; // pending ActivityResult objs we have received
HashSet<WeakReference<PendingIntentRecord>> pendingResults; // all pending intents for this act
- ArrayList<Intent> newIntents; // any pending new intents for single-top mode
+ ArrayList<ReferrerIntent> newIntents; // any pending new intents for single-top mode
ActivityOptions pendingOptions; // most recently given options
ActivityOptions returningOptions; // options that are coming back via convertToTranslucent
HashSet<ConnectionRecord> connections; // All ConnectionRecord we hold
@@ -629,9 +630,9 @@
}
}
- void addNewIntentLocked(Intent intent) {
+ void addNewIntentLocked(ReferrerIntent intent) {
if (newIntents == null) {
- newIntents = new ArrayList<Intent>();
+ newIntents = new ArrayList<>();
}
newIntents.add(intent);
}
@@ -640,7 +641,7 @@
* Deliver a new Intent to an existing activity, so that its onNewIntent()
* method will be called at the proper time.
*/
- final void deliverNewIntentLocked(int callingUid, Intent intent) {
+ final void deliverNewIntentLocked(int callingUid, Intent intent, String referrer) {
// The activity now gets access to the data associated with this Intent.
service.grantUriPermissionFromIntentLocked(callingUid, packageName,
intent, getUriPermissionsLocked(), userId);
@@ -649,14 +650,14 @@
// device is sleeping, then all activities are stopped, so in that
// case we will deliver it if this is the current top activity on its
// stack.
+ final ReferrerIntent rintent = new ReferrerIntent(intent, referrer);
boolean unsent = true;
if ((state == ActivityState.RESUMED || (service.isSleeping()
&& task.stack.topRunningActivityLocked(null) == this))
&& app != null && app.thread != null) {
try {
- ArrayList<Intent> ar = new ArrayList<Intent>();
- intent = new Intent(intent);
- ar.add(intent);
+ ArrayList<ReferrerIntent> ar = new ArrayList<>(1);
+ ar.add(rintent);
app.thread.scheduleNewIntent(ar, appToken);
unsent = false;
} catch (RemoteException e) {
@@ -668,7 +669,7 @@
}
}
if (unsent) {
- addNewIntentLocked(new Intent(intent));
+ addNewIntentLocked(rintent);
}
}
diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java
old mode 100755
new mode 100644
index b955011..0dae028
--- a/services/core/java/com/android/server/am/ActivityStack.java
+++ b/services/core/java/com/android/server/am/ActivityStack.java
@@ -44,6 +44,7 @@
import android.util.ArraySet;
import com.android.internal.app.IVoiceInteractor;
+import com.android.internal.content.ReferrerIntent;
import com.android.internal.os.BatteryStatsImpl;
import com.android.server.Watchdog;
import com.android.server.am.ActivityManagerService.ItemMatcher;
@@ -1642,8 +1643,8 @@
boolean dontWaitForPause = (next.info.flags&ActivityInfo.FLAG_RESUME_WHILE_PAUSING) != 0;
boolean pausing = mStackSupervisor.pauseBackStacks(userLeaving, true, dontWaitForPause);
if (mResumedActivity != null) {
- pausing |= startPausingLocked(userLeaving, false, true, dontWaitForPause);
if (DEBUG_STATES) Slog.d(TAG, "resumeTopActivityLocked: Pausing " + mResumedActivity);
+ pausing |= startPausingLocked(userLeaving, false, true, dontWaitForPause);
}
if (pausing) {
if (DEBUG_SWITCH || DEBUG_STATES) Slog.v(TAG,
@@ -2953,7 +2954,8 @@
parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TASK ||
parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TOP ||
(destIntentFlags & Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0) {
- parent.deliverNewIntentLocked(srec.info.applicationInfo.uid, destIntent);
+ parent.deliverNewIntentLocked(srec.info.applicationInfo.uid, destIntent,
+ srec.packageName);
} else {
try {
ActivityInfo aInfo = AppGlobals.getPackageManager().getActivityInfo(
@@ -3773,7 +3775,7 @@
private boolean relaunchActivityLocked(ActivityRecord r,
int changes, boolean andResume) {
List<ResultInfo> results = null;
- List<Intent> newIntents = null;
+ List<ReferrerIntent> newIntents = null;
if (andResume) {
results = r.results;
newIntents = r.newIntents;
diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
index 079df7d..099151f 100644
--- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
@@ -97,6 +97,7 @@
import android.view.Surface;
import com.android.internal.app.HeavyWeightSwitcherActivity;
import com.android.internal.app.IVoiceInteractor;
+import com.android.internal.content.ReferrerIntent;
import com.android.internal.os.TransferPipe;
import com.android.internal.statusbar.IStatusBarService;
import com.android.internal.widget.LockPatternUtils;
@@ -1101,7 +1102,7 @@
throw new RemoteException();
}
List<ResultInfo> results = null;
- List<Intent> newIntents = null;
+ List<ReferrerIntent> newIntents = null;
if (andResume) {
results = r.results;
newIntents = r.newIntents;
@@ -1155,9 +1156,9 @@
app.forceProcessStateUpTo(ActivityManager.PROCESS_STATE_TOP);
app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken,
System.identityHashCode(r), r.info, new Configuration(mService.mConfiguration),
- r.compat, r.task.voiceInteractor, app.repProcState, r.icicle, r.persistentState,
- results, newIntents, !andResume, mService.isNextTransitionForward(),
- profilerInfo);
+ r.compat, r.launchedFromPackage, r.task.voiceInteractor, app.repProcState,
+ r.icicle, r.persistentState, results, newIntents, !andResume,
+ mService.isNextTransitionForward(), profilerInfo);
if ((app.info.flags&ApplicationInfo.FLAG_CANT_SAVE_STATE) != 0) {
// This may be a heavy-weight process! Note that the package
@@ -1896,7 +1897,7 @@
}
ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT,
r, top.task);
- top.deliverNewIntentLocked(callingUid, r.intent);
+ top.deliverNewIntentLocked(callingUid, r.intent, r.launchedFromPackage);
} else {
// A special case: we need to
// start the activity because it is not currently
@@ -1922,7 +1923,8 @@
if (intentActivity.frontOfTask) {
intentActivity.task.setIntent(r);
}
- intentActivity.deliverNewIntentLocked(callingUid, r.intent);
+ intentActivity.deliverNewIntentLocked(callingUid, r.intent,
+ r.launchedFromPackage);
} else if (!r.intent.filterEquals(intentActivity.task.intent)) {
// In this case we are launching the root activity
// of the task, but with a different intent. We
@@ -1995,7 +1997,7 @@
// is the case, so this is it!
return ActivityManager.START_RETURN_INTENT_TO_CALLER;
}
- top.deliverNewIntentLocked(callingUid, r.intent);
+ top.deliverNewIntentLocked(callingUid, r.intent, r.launchedFromPackage);
return ActivityManager.START_DELIVERED_TO_TOP;
}
}
@@ -2071,7 +2073,7 @@
keepCurTransition = true;
if (top != null) {
ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, r, top.task);
- top.deliverNewIntentLocked(callingUid, r.intent);
+ top.deliverNewIntentLocked(callingUid, r.intent, r.launchedFromPackage);
// For paranoia, make sure we have correctly
// resumed the top activity.
targetStack.mLastPausedActivity = null;
@@ -2092,7 +2094,7 @@
task.moveActivityToFrontLocked(top);
ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, r, task);
top.updateOptionsLocked(options);
- top.deliverNewIntentLocked(callingUid, r.intent);
+ top.deliverNewIntentLocked(callingUid, r.intent, r.launchedFromPackage);
targetStack.mLastPausedActivity = null;
if (doResume) {
targetStack.resumeTopActivityLocked(null);
@@ -2132,7 +2134,7 @@
// is the case, so this is it!
return ActivityManager.START_RETURN_INTENT_TO_CALLER;
}
- top.deliverNewIntentLocked(callingUid, r.intent);
+ top.deliverNewIntentLocked(callingUid, r.intent, r.launchedFromPackage);
return ActivityManager.START_DELIVERED_TO_TOP;
}
}
diff --git a/services/core/java/com/android/server/am/ProcessList.java b/services/core/java/com/android/server/am/ProcessList.java
index a4aff77..843a0cb 100644
--- a/services/core/java/com/android/server/am/ProcessList.java
+++ b/services/core/java/com/android/server/am/ProcessList.java
@@ -177,7 +177,7 @@
// 1280x800 or larger screen with around 1GB RAM. Values are in KB.
private final int[] mOomMinFreeHigh = new int[] {
73728, 92160, 110592,
- 129024, 225000, 325000
+ 129024, 147456, 184320
};
// The actual OOM killer memory levels we are using.
private final int[] mOomMinFree = new int[mOomAdj.length];
diff --git a/services/core/java/com/android/server/input/InputWindowHandle.java b/services/core/java/com/android/server/input/InputWindowHandle.java
index 9a70f38..9149fcc 100644
--- a/services/core/java/com/android/server/input/InputWindowHandle.java
+++ b/services/core/java/com/android/server/input/InputWindowHandle.java
@@ -44,7 +44,6 @@
// Window layout params attributes. (WindowManager.LayoutParams)
public int layoutParamsFlags;
- public int layoutParamsPrivateFlags;
public int layoutParamsType;
// Dispatching timeout.
diff --git a/services/core/java/com/android/server/location/GpsLocationProvider.java b/services/core/java/com/android/server/location/GpsLocationProvider.java
index 86aa516..2c9a468 100644
--- a/services/core/java/com/android/server/location/GpsLocationProvider.java
+++ b/services/core/java/com/android/server/location/GpsLocationProvider.java
@@ -72,6 +72,9 @@
import android.provider.Telephony.Carriers;
import android.provider.Telephony.Sms.Intents;
import android.telephony.SmsMessage;
+import android.telephony.SubscriptionInfo;
+import android.telephony.SubscriptionListener;
+import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
import android.telephony.gsm.GsmCellLocation;
import android.text.TextUtils;
@@ -88,6 +91,7 @@
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.Date;
+import java.util.List;
import java.util.Map.Entry;
import java.util.Properties;
@@ -452,26 +456,35 @@
|| Intent.ACTION_SCREEN_OFF.equals(action)
|| Intent.ACTION_SCREEN_ON.equals(action)) {
updateLowPowerMode();
- } else if (action.equals(SIM_STATE_CHANGED)
- || action.equals(TelephonyIntents.ACTION_SUBINFO_CONTENT_CHANGE)
- || action.equals(TelephonyIntents.ACTION_SUBINFO_RECORD_UPDATED)) {
- Log.d(TAG, "received SIM realted action: " + action);
- TelephonyManager phone = (TelephonyManager)
- mContext.getSystemService(Context.TELEPHONY_SERVICE);
- String mccMnc = phone.getSimOperator();
- if (!TextUtils.isEmpty(mccMnc)) {
- Log.d(TAG, "SIM MCC/MNC is available: " + mccMnc);
- synchronized (mLock) {
- reloadGpsProperties(context, mProperties);
- mNIHandler.setSuplEsEnabled(mSuplEsEnabled);
- }
- } else {
- Log.d(TAG, "SIM MCC/MNC is still not available");
- }
+ } else if (action.equals(SIM_STATE_CHANGED)) {
+ subscriptionOrSimChanged(context);
}
}
};
+ private final SubscriptionListener mSubscriptionListener = new SubscriptionListener() {
+ @Override
+ public void onSubscriptionInfoChanged() {
+ subscriptionOrSimChanged(mContext);
+ }
+ };
+
+ private void subscriptionOrSimChanged(Context context) {
+ Log.d(TAG, "received SIM realted action: ");
+ TelephonyManager phone = (TelephonyManager)
+ mContext.getSystemService(Context.TELEPHONY_SERVICE);
+ String mccMnc = phone.getSimOperator();
+ if (!TextUtils.isEmpty(mccMnc)) {
+ Log.d(TAG, "SIM MCC/MNC is available: " + mccMnc);
+ synchronized (mLock) {
+ reloadGpsProperties(context, mProperties);
+ mNIHandler.setSuplEsEnabled(mSuplEsEnabled);
+ }
+ } else {
+ Log.d(TAG, "SIM MCC/MNC is still not available");
+ }
+ }
+
private void checkSmsSuplInit(Intent intent) {
SmsMessage[] messages = Intents.getMessagesFromIntent(intent);
for (int i=0; i <messages.length; i++) {
@@ -626,6 +639,16 @@
mNetInitiatedListener,
mSuplEsEnabled);
+ // TODO: When this object "finishes" we should unregister by invoking
+ // SubscriptionManager.unregister(mContext, mSubscriptionListener);
+ // This is not strictly necessary because it will be unregistered if the
+ // notification fails but it is good form.
+
+ // Register for SubscriptionInfo list changes which is guaranteed
+ // to invoke onSubscriptionInfoChanged the first time.
+ SubscriptionManager.register(mContext, mSubscriptionListener,
+ SubscriptionListener.LISTEN_SUBSCRIPTION_INFO_LIST_CHANGED);
+
// construct handler, listen for events
mHandler = new ProviderHandler(looper);
listenForBroadcasts();
@@ -735,10 +758,6 @@
intentFilter.addAction(Intent.ACTION_SCREEN_OFF);
intentFilter.addAction(Intent.ACTION_SCREEN_ON);
intentFilter.addAction(SIM_STATE_CHANGED);
- // TODO: remove the use TelephonyIntents. We are using it because SIM_STATE_CHANGED
- // is not reliable at the moment.
- intentFilter.addAction(TelephonyIntents.ACTION_SUBINFO_CONTENT_CHANGE);
- intentFilter.addAction(TelephonyIntents.ACTION_SUBINFO_RECORD_UPDATED);
mContext.registerReceiver(mBroadcastReceiver, intentFilter, null, mHandler);
}
@@ -895,7 +914,7 @@
AsyncTask.THREAD_POOL_EXECUTOR.execute(new Runnable() {
@Override
public void run() {
- GpsXtraDownloader xtraDownloader = new GpsXtraDownloader(mContext, mProperties);
+ GpsXtraDownloader xtraDownloader = new GpsXtraDownloader(mProperties);
byte[] data = xtraDownloader.downloadXtraData();
if (data != null) {
if (DEBUG) {
diff --git a/services/core/java/com/android/server/location/GpsXtraDownloader.java b/services/core/java/com/android/server/location/GpsXtraDownloader.java
index a5eef6a..c820a43 100644
--- a/services/core/java/com/android/server/location/GpsXtraDownloader.java
+++ b/services/core/java/com/android/server/location/GpsXtraDownloader.java
@@ -17,20 +17,14 @@
package com.android.server.location;
import android.content.Context;
-import android.net.Proxy;
-import android.net.http.AndroidHttpClient;
import android.text.TextUtils;
import android.util.Log;
-import org.apache.http.HttpEntity;
-import org.apache.http.HttpHost;
-import org.apache.http.HttpResponse;
-import org.apache.http.StatusLine;
-import org.apache.http.client.methods.HttpGet;
-import org.apache.http.client.methods.HttpUriRequest;
-import org.apache.http.conn.params.ConnRouteParams;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import libcore.io.IoUtils;
+import libcore.io.Streams;
-import java.io.DataInputStream;
import java.io.IOException;
import java.util.Properties;
import java.util.Random;
@@ -46,15 +40,12 @@
private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
private static final String DEFAULT_USER_AGENT = "Android";
- private final Context mContext;
private final String[] mXtraServers;
// to load balance our server requests
private int mNextServerIndex;
private final String mUserAgent;
- GpsXtraDownloader(Context context, Properties properties) {
- mContext = context;
-
+ GpsXtraDownloader(Properties properties) {
// read XTRA servers from the Properties object
int count = 0;
String server1 = properties.getProperty("XTRA_SERVER_1");
@@ -75,7 +66,6 @@
if (count == 0) {
Log.e(TAG, "No XTRA servers were specified in the GPS configuration");
mXtraServers = null;
- return;
} else {
mXtraServers = new String[count];
count = 0;
@@ -90,9 +80,6 @@
}
byte[] downloadXtraData() {
- String proxyHost = Proxy.getHost(mContext);
- int proxyPort = Proxy.getPort(mContext);
- boolean useProxy = (proxyHost != null && proxyPort != -1);
byte[] result = null;
int startIndex = mNextServerIndex;
@@ -102,7 +89,7 @@
// load balance our requests among the available servers
while (result == null) {
- result = doDownload(mXtraServers[mNextServerIndex], useProxy, proxyHost, proxyPort);
+ result = doDownload(mXtraServers[mNextServerIndex]);
// increment mNextServerIndex and wrap around if necessary
mNextServerIndex++;
@@ -116,65 +103,32 @@
return result;
}
- protected byte[] doDownload(String url, boolean isProxySet,
- String proxyHost, int proxyPort) {
+ protected byte[] doDownload(String url) {
if (DEBUG) Log.d(TAG, "Downloading XTRA data from " + url);
- AndroidHttpClient client = null;
+ HttpURLConnection connection = null;
try {
- if (DEBUG) Log.d(TAG, "XTRA user agent: " + mUserAgent);
- client = AndroidHttpClient.newInstance(mUserAgent);
- HttpUriRequest req = new HttpGet(url);
-
- if (isProxySet) {
- HttpHost proxy = new HttpHost(proxyHost, proxyPort);
- ConnRouteParams.setDefaultProxy(req.getParams(), proxy);
- }
-
- req.addHeader(
+ connection = (HttpURLConnection) (new URL(url)).openConnection();
+ connection.setRequestProperty(
"Accept",
"*/*, application/vnd.wap.mms-message, application/vnd.wap.sic");
-
- req.addHeader(
+ connection.setRequestProperty(
"x-wap-profile",
"http://www.openmobilealliance.org/tech/profiles/UAPROF/ccppschema-20021212#");
- HttpResponse response = client.execute(req);
- StatusLine status = response.getStatusLine();
- if (status.getStatusCode() != 200) { // HTTP 200 is success.
- if (DEBUG) Log.d(TAG, "HTTP error: " + status.getReasonPhrase());
+ connection.connect();
+ int statusCode = connection.getResponseCode();
+ if (statusCode != HttpURLConnection.HTTP_OK) {
+ if (DEBUG) Log.d(TAG, "HTTP error downloading gps XTRA: " + statusCode);
return null;
}
- HttpEntity entity = response.getEntity();
- byte[] body = null;
- if (entity != null) {
- try {
- if (entity.getContentLength() > 0) {
- body = new byte[(int) entity.getContentLength()];
- DataInputStream dis = new DataInputStream(entity.getContent());
- try {
- dis.readFully(body);
- } finally {
- try {
- dis.close();
- } catch (IOException e) {
- Log.e(TAG, "Unexpected IOException.", e);
- }
- }
- }
- } finally {
- if (entity != null) {
- entity.consumeContent();
- }
- }
- }
- return body;
- } catch (Exception e) {
- if (DEBUG) Log.d(TAG, "error " + e);
+ return Streams.readFully(connection.getInputStream());
+ } catch (IOException ioe) {
+ if (DEBUG) Log.d(TAG, "Error downloading gps XTRA: ", ioe);
} finally {
- if (client != null) {
- client.close();
+ if (connection != null) {
+ connection.disconnect();
}
}
return null;
diff --git a/services/core/java/com/android/server/media/MediaSessionRecord.java b/services/core/java/com/android/server/media/MediaSessionRecord.java
index 921b68b..2531082 100644
--- a/services/core/java/com/android/server/media/MediaSessionRecord.java
+++ b/services/core/java/com/android/server/media/MediaSessionRecord.java
@@ -28,6 +28,9 @@
import android.media.MediaMetadata;
import android.media.Rating;
import android.media.VolumeProvider;
+import android.media.routing.IMediaRouter;
+import android.media.routing.IMediaRouterDelegate;
+import android.media.routing.IMediaRouterStateCallback;
import android.media.session.ISession;
import android.media.session.ISessionCallback;
import android.media.session.ISessionController;
@@ -96,6 +99,7 @@
new ArrayList<ISessionControllerCallback>();
private long mFlags;
+ private IMediaRouter mMediaRouter;
private PendingIntent mMediaButtonReceiver;
private PendingIntent mLaunchIntent;
@@ -714,6 +718,12 @@
}
@Override
+ public void setMediaRouter(IMediaRouter router) {
+ mMediaRouter = router;
+ mHandler.post(MessageHandler.MSG_UPDATE_SESSION_STATE);
+ }
+
+ @Override
public void setMediaButtonReceiver(PendingIntent pi) {
mMediaButtonReceiver = pi;
}
@@ -1185,6 +1195,13 @@
public boolean isTransportControlEnabled() {
return MediaSessionRecord.this.isTransportControlEnabled();
}
+
+ @Override
+ public IMediaRouterDelegate createMediaRouterDelegate(
+ IMediaRouterStateCallback callback) {
+ // todo
+ return null;
+ }
}
private class MessageHandler extends Handler {
diff --git a/services/core/java/com/android/server/notification/DowntimeConditionProvider.java b/services/core/java/com/android/server/notification/DowntimeConditionProvider.java
index 24fd155..0fb5732 100644
--- a/services/core/java/com/android/server/notification/DowntimeConditionProvider.java
+++ b/services/core/java/com/android/server/notification/DowntimeConditionProvider.java
@@ -18,6 +18,7 @@
import android.app.AlarmManager;
import android.app.PendingIntent;
+import android.app.AlarmManager.AlarmClockInfo;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
@@ -63,8 +64,10 @@
private final Calendar mCalendar = Calendar.getInstance();
private final Context mContext = this;
private final ArraySet<Integer> mDays = new ArraySet<Integer>();
+ private final ArraySet<Long> mFiredAlarms = new ArraySet<Long>();
private boolean mConnected;
+ private NextAlarmTracker mTracker;
private int mDowntimeMode;
private ZenModeConfig mConfig;
private Callback mCallback;
@@ -77,6 +80,7 @@
pw.println(" DowntimeConditionProvider:");
pw.print(" mConnected="); pw.println(mConnected);
pw.print(" mDowntimeMode="); pw.println(Global.zenModeToString(mDowntimeMode));
+ pw.print(" mFiredAlarms="); pw.println(mFiredAlarms);
}
public void attachBase(Context base) {
@@ -101,12 +105,15 @@
filter.addAction(Intent.ACTION_TIME_CHANGED);
filter.addAction(Intent.ACTION_TIMEZONE_CHANGED);
mContext.registerReceiver(mReceiver, filter);
+ mTracker = mCallback.getNextAlarmTracker();
+ mTracker.addCallback(mTrackerCallback);
init();
}
@Override
public void onDestroy() {
if (DEBUG) Slog.d(TAG, "onDestroy");
+ mTracker.removeCallback(mTrackerCallback);
mConnected = false;
}
@@ -183,35 +190,52 @@
}
}
- private int computeDowntimeMode(long time) {
- if (mConfig == null || mDays.size() == 0) return Global.ZEN_MODE_OFF;
+ private boolean isInDowntime(long time) {
+ if (mConfig == null || mDays.size() == 0) return false;
final long start = getTime(time, mConfig.sleepStartHour, mConfig.sleepStartMinute);
long end = getTime(time, mConfig.sleepEndHour, mConfig.sleepEndMinute);
- if (start == end) return Global.ZEN_MODE_OFF;
+ if (start == end) return false;
if (end < start) {
end = addDays(end, 1);
}
- final boolean inDowntime = isInDowntime(-1, time, start, end)
- || isInDowntime(0, time, start, end);
- return inDowntime ? (mConfig.sleepNone ? Global.ZEN_MODE_NO_INTERRUPTIONS
- : Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS) : Global.ZEN_MODE_OFF;
+ final boolean orAlarm = mConfig.sleepNone;
+ return isInDowntime(-1, time, start, end, orAlarm)
+ || isInDowntime(0, time, start, end, orAlarm);
}
- private boolean isInDowntime(int daysOffset, long time, long start, long end) {
+ private boolean isInDowntime(int daysOffset, long time, long start, long end, boolean orAlarm) {
final int n = Calendar.SATURDAY;
final int day = ((getDayOfWeek(time) - 1) + (daysOffset % n) + n) % n + 1;
start = addDays(start, daysOffset);
end = addDays(end, daysOffset);
+ if (orAlarm) {
+ end = findFiredAlarm(start, end);
+ }
return mDays.contains(day) && time >= start && time < end;
}
+ private long findFiredAlarm(long start, long end) {
+ final int N = mFiredAlarms.size();
+ for (int i = 0; i < N; i++) {
+ final long firedAlarm = mFiredAlarms.valueAt(i);
+ if (firedAlarm > start && firedAlarm < end) {
+ return firedAlarm;
+ }
+ }
+ return end;
+ }
+
private void reevaluateDowntime() {
- final int downtimeMode = computeDowntimeMode(System.currentTimeMillis());
+ final long now = System.currentTimeMillis();
+ final boolean inDowntimeNow = isInDowntime(now);
+ final int downtimeMode = inDowntimeNow ? (mConfig.sleepNone
+ ? Global.ZEN_MODE_NO_INTERRUPTIONS : Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS)
+ : Global.ZEN_MODE_OFF;
if (DEBUG) Slog.d(TAG, "downtimeMode=" + downtimeMode);
if (downtimeMode == mDowntimeMode) return;
mDowntimeMode = downtimeMode;
Slog.i(TAG, (isInDowntime() ? "Entering" : "Exiting" ) + " downtime");
- ZenLog.traceDowntime(mDowntimeMode, getDayOfWeek(System.currentTimeMillis()), mDays);
+ ZenLog.traceDowntime(mDowntimeMode, getDayOfWeek(now), mDays);
fireDowntimeChanged();
}
@@ -266,8 +290,8 @@
PendingIntent.FLAG_UPDATE_CURRENT);
alarms.cancel(pendingIntent);
if (mConfig.sleepMode != null) {
- if (DEBUG) Slog.d(TAG, String.format("Scheduling %s for %s, %s in the future, now=%s",
- action, ts(time), time - now, ts(now)));
+ if (DEBUG) Slog.d(TAG, String.format("Scheduling %s for %s, in %s, now=%s",
+ action, ts(time), NextAlarmTracker.formatDuration(time - now), ts(now)));
alarms.setExact(AlarmManager.RTC_WAKEUP, time, pendingIntent);
}
}
@@ -276,6 +300,30 @@
return new Date(time) + " (" + time + ")";
}
+ private void onEvaluateNextAlarm(AlarmClockInfo nextAlarm, long wakeupTime, boolean booted) {
+ if (!booted) return; // we don't know yet
+ if (nextAlarm == null) return; // not fireable
+ if (DEBUG) Slog.d(TAG, "onEvaluateNextAlarm " + mTracker.formatAlarmDebug(nextAlarm));
+ if (System.currentTimeMillis() > wakeupTime) {
+ if (DEBUG) Slog.d(TAG, "Alarm fired: " + mTracker.formatAlarmDebug(wakeupTime));
+ trimFiredAlarms();
+ mFiredAlarms.add(wakeupTime);
+ }
+ reevaluateDowntime();
+ }
+
+ private void trimFiredAlarms() {
+ // remove fired alarms over 2 days old
+ final long keepAfter = System.currentTimeMillis() - 2 * 24 * 60 * 60 * 1000;
+ final int N = mFiredAlarms.size();
+ for (int i = N - 1; i >= 0; i--) {
+ final long firedAlarm = mFiredAlarms.valueAt(i);
+ if (firedAlarm < keepAfter) {
+ mFiredAlarms.removeAt(i);
+ }
+ }
+ }
+
private BroadcastReceiver mReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
@@ -296,6 +344,13 @@
}
};
+ private final NextAlarmTracker.Callback mTrackerCallback = new NextAlarmTracker.Callback() {
+ @Override
+ public void onEvaluate(AlarmClockInfo nextAlarm, long wakeupTime, boolean booted) {
+ DowntimeConditionProvider.this.onEvaluateNextAlarm(nextAlarm, wakeupTime, booted);
+ }
+ };
+
public interface Callback {
void onDowntimeChanged(int downtimeMode);
NextAlarmTracker getNextAlarmTracker();
diff --git a/services/core/java/com/android/server/notification/NextAlarmTracker.java b/services/core/java/com/android/server/notification/NextAlarmTracker.java
index d197afd..234f545 100644
--- a/services/core/java/com/android/server/notification/NextAlarmTracker.java
+++ b/services/core/java/com/android/server/notification/NextAlarmTracker.java
@@ -176,7 +176,7 @@
return true;
}
- private static String formatDuration(long millis) {
+ public static String formatDuration(long millis) {
final StringBuilder sb = new StringBuilder();
TimeUtils.formatDuration(millis, sb);
return sb.toString();
@@ -196,7 +196,7 @@
return DateFormat.format(pattern, time).toString();
}
- private String formatAlarmDebug(AlarmClockInfo alarm) {
+ public String formatAlarmDebug(AlarmClockInfo alarm) {
return formatAlarmDebug(alarm != null ? alarm.getTriggerTime() : 0);
}
diff --git a/services/core/java/com/android/server/notification/NotificationUsageStats.java b/services/core/java/com/android/server/notification/NotificationUsageStats.java
index 8278c4f..3d13d21 100644
--- a/services/core/java/com/android/server/notification/NotificationUsageStats.java
+++ b/services/core/java/com/android/server/notification/NotificationUsageStats.java
@@ -49,7 +49,7 @@
// WARNING: Aggregated stats can grow unboundedly with pkg+id+tag.
// Don't enable on production builds.
private static final boolean ENABLE_AGGREGATED_IN_MEMORY_STATS = false;
- private static final boolean ENABLE_SQLITE_LOG = false;
+ private static final boolean ENABLE_SQLITE_LOG = true;
private static final AggregatedStats[] EMPTY_AGGREGATED_STATS = new AggregatedStats[0];
diff --git a/services/core/java/com/android/server/notification/ValidateNotificationPeople.java b/services/core/java/com/android/server/notification/ValidateNotificationPeople.java
index 11d00cf..5eb318b 100644
--- a/services/core/java/com/android/server/notification/ValidateNotificationPeople.java
+++ b/services/core/java/com/android/server/notification/ValidateNotificationPeople.java
@@ -219,7 +219,7 @@
return null;
}
- if (INFO) Slog.i(TAG, "Validating: " + key);
+ if (INFO) Slog.i(TAG, "Validating: " + key + " for " + context.getUserId());
final LinkedList<String> pendingLookups = new LinkedList<String>();
for (int personIdx = 0; personIdx < people.length && personIdx < MAX_PEOPLE; personIdx++) {
final String handle = people[personIdx];
@@ -443,7 +443,10 @@
final String cacheKey = getCacheKey(mContext.getUserId(), handle);
mPeopleCache.put(cacheKey, lookupResult);
}
+ if (DEBUG) Slog.d(TAG, "lookup contactAffinity is " + lookupResult.getAffinity());
mContactAffinity = Math.max(mContactAffinity, lookupResult.getAffinity());
+ } else {
+ if (DEBUG) Slog.d(TAG, "lookupResult is null");
}
}
if (DEBUG) {
diff --git a/services/core/java/com/android/server/pm/SELinuxMMAC.java b/services/core/java/com/android/server/pm/SELinuxMMAC.java
index 81302b9..98f2997 100644
--- a/services/core/java/com/android/server/pm/SELinuxMMAC.java
+++ b/services/core/java/com/android/server/pm/SELinuxMMAC.java
@@ -137,6 +137,14 @@
}
public static boolean readInstallPolicy() {
+ return readInstallPolicy(MAC_PERMISSIONS);
+ }
+
+ public static boolean readInstallPolicy(String macPermsPath) {
+ if (macPermsPath == null) {
+ throw new NullPointerException("mac_permissions.xml file path is null");
+ }
+
// Temp structures to hold the rules while we parse the xml file.
// We add all the rules together once we know there's no structural problems.
HashMap<Signature, Policy> sigSeinfo = new HashMap<Signature, Policy>();
@@ -144,8 +152,8 @@
FileReader policyFile = null;
try {
- policyFile = new FileReader(MAC_PERMISSIONS);
- Slog.d(TAG, "Using policy file " + MAC_PERMISSIONS);
+ policyFile = new FileReader(macPermsPath);
+ Slog.d(TAG, "Using policy file " + macPermsPath);
XmlPullParser parser = Xml.newPullParser();
parser.setInput(policyFile);
@@ -190,10 +198,10 @@
}
}
} catch (XmlPullParserException xpe) {
- Slog.w(TAG, "Got exception parsing " + MAC_PERMISSIONS, xpe);
+ Slog.w(TAG, "Got exception parsing " + macPermsPath, xpe);
return false;
} catch (IOException ioe) {
- Slog.w(TAG, "Got exception parsing " + MAC_PERMISSIONS, ioe);
+ Slog.w(TAG, "Got exception parsing " + macPermsPath, ioe);
return false;
} finally {
IoUtils.closeQuietly(policyFile);
diff --git a/services/core/java/com/android/server/power/PowerManagerService.java b/services/core/java/com/android/server/power/PowerManagerService.java
index 8682f5c..c054e6c 100644
--- a/services/core/java/com/android/server/power/PowerManagerService.java
+++ b/services/core/java/com/android/server/power/PowerManagerService.java
@@ -3141,21 +3141,6 @@
}
/**
- * Used by device administration to set the maximum screen off timeout.
- *
- * This method must only be called by the device administration policy manager.
- */
- @Override // Binder call
- public void setMaximumScreenOffTimeoutFromDeviceAdmin(int timeMs) {
- final long ident = Binder.clearCallingIdentity();
- try {
- setMaximumScreenOffTimeoutFromDeviceAdminInternal(timeMs);
- } finally {
- Binder.restoreCallingIdentity(ident);
- }
- }
-
- /**
* Used by the settings application and brightness control widgets to
* temporarily override the current screen brightness setting so that the
* user can observe the effect of an intended settings change without applying
@@ -3300,6 +3285,11 @@
}
@Override
+ public void setMaximumScreenOffTimeoutFromDeviceAdmin(int timeMs) {
+ setMaximumScreenOffTimeoutFromDeviceAdminInternal(timeMs);
+ }
+
+ @Override
public boolean getLowPowerModeEnabled() {
synchronized (mLock) {
return mLowPowerModeEnabled;
diff --git a/services/core/java/com/android/server/wm/AppWindowToken.java b/services/core/java/com/android/server/wm/AppWindowToken.java
index b2575e6..1086eb2 100644
--- a/services/core/java/com/android/server/wm/AppWindowToken.java
+++ b/services/core/java/com/android/server/wm/AppWindowToken.java
@@ -252,11 +252,17 @@
return false;
}
+ @Override
void removeAllWindows() {
- for (int winNdx = allAppWindows.size() - 1; winNdx >= 0; --winNdx) {
- WindowState win = allAppWindows.get(winNdx);
- if (WindowManagerService.DEBUG_WINDOW_MOVEMENT) Slog.w(WindowManagerService.TAG,
- "removeAllWindows: removing win=" + win);
+ int winNdx;
+ while ((winNdx = allAppWindows.size()) > 0) {
+ WindowState win = allAppWindows.get(winNdx - 1);
+ if (WindowManagerService.DEBUG_WINDOW_MOVEMENT) {
+ Slog.w(WindowManagerService.TAG, "removeAllWindows: removing win=" + win);
+ }
+
+ // {@link WindowManagerService.removeWindowLocked} may remove multiple entries from
+ // {@link #allAppWindows} if the window to be removed has child windows.
win.mService.removeWindowLocked(win.mSession, win);
}
}
diff --git a/services/core/java/com/android/server/wm/DragState.java b/services/core/java/com/android/server/wm/DragState.java
index edc7c93..c6951bd 100644
--- a/services/core/java/com/android/server/wm/DragState.java
+++ b/services/core/java/com/android/server/wm/DragState.java
@@ -114,7 +114,6 @@
mDragWindowHandle.inputChannel = mServerChannel;
mDragWindowHandle.layer = getDragLayerLw();
mDragWindowHandle.layoutParamsFlags = 0;
- mDragWindowHandle.layoutParamsPrivateFlags = 0;
mDragWindowHandle.layoutParamsType = WindowManager.LayoutParams.TYPE_DRAG;
mDragWindowHandle.dispatchingTimeoutNanos =
WindowManagerService.DEFAULT_INPUT_DISPATCHING_TIMEOUT_NANOS;
diff --git a/services/core/java/com/android/server/wm/FakeWindowImpl.java b/services/core/java/com/android/server/wm/FakeWindowImpl.java
index c18ea01..1136ced 100644
--- a/services/core/java/com/android/server/wm/FakeWindowImpl.java
+++ b/services/core/java/com/android/server/wm/FakeWindowImpl.java
@@ -38,7 +38,7 @@
public FakeWindowImpl(WindowManagerService service,
Looper looper, InputEventReceiver.Factory inputEventReceiverFactory,
- String name, int windowType, int layoutParamsFlags, int layoutParamsPrivateFlags,
+ String name, int windowType, int layoutParamsFlags,
boolean canReceiveKeys, boolean hasFocus, boolean touchFullscreen) {
mService = service;
@@ -61,7 +61,6 @@
mWindowLayer = getLayerLw(windowType);
mWindowHandle.layer = mWindowLayer;
mWindowHandle.layoutParamsFlags = layoutParamsFlags;
- mWindowHandle.layoutParamsPrivateFlags = layoutParamsPrivateFlags;
mWindowHandle.layoutParamsType = windowType;
mWindowHandle.dispatchingTimeoutNanos =
WindowManagerService.DEFAULT_INPUT_DISPATCHING_TIMEOUT_NANOS;
diff --git a/services/core/java/com/android/server/wm/InputMonitor.java b/services/core/java/com/android/server/wm/InputMonitor.java
index 46aefb6..0327cb3 100644
--- a/services/core/java/com/android/server/wm/InputMonitor.java
+++ b/services/core/java/com/android/server/wm/InputMonitor.java
@@ -168,8 +168,8 @@
}
private void addInputWindowHandleLw(final InputWindowHandle inputWindowHandle,
- final WindowState child, int flags, int privateFlags, final int type,
- final boolean isVisible, final boolean hasFocus, final boolean hasWallpaper) {
+ final WindowState child, int flags, final int type, final boolean isVisible,
+ final boolean hasFocus, final boolean hasWallpaper) {
// Add a window to our list of input windows.
inputWindowHandle.name = child.toString();
final boolean modal = (flags & (WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
@@ -184,7 +184,6 @@
child.getTouchableRegion(inputWindowHandle.touchableRegion);
}
inputWindowHandle.layoutParamsFlags = flags;
- inputWindowHandle.layoutParamsPrivateFlags = privateFlags;
inputWindowHandle.layoutParamsType = type;
inputWindowHandle.dispatchingTimeoutNanos = child.getInputDispatchingTimeoutNanos();
inputWindowHandle.visible = isVisible;
@@ -298,15 +297,14 @@
final WindowState u = universeBackground.mWin;
if (u.mInputChannel != null && u.mInputWindowHandle != null) {
addInputWindowHandleLw(u.mInputWindowHandle, u, u.mAttrs.flags,
- u.mAttrs.privateFlags, u.mAttrs.type,
- true, u == mInputFocus, false);
+ u.mAttrs.type, true, u == mInputFocus, false);
}
addedUniverse = true;
}
if (child.mWinAnimator != universeBackground) {
- addInputWindowHandleLw(inputWindowHandle, child, flags, privateFlags, type,
- isVisible, hasFocus, hasWallpaper);
+ addInputWindowHandleLw(inputWindowHandle, child, flags, type, isVisible,
+ hasFocus, hasWallpaper);
}
}
}
diff --git a/services/core/java/com/android/server/wm/WindowAnimator.java b/services/core/java/com/android/server/wm/WindowAnimator.java
index c002ddf..82e4bb1 100644
--- a/services/core/java/com/android/server/wm/WindowAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowAnimator.java
@@ -20,6 +20,7 @@
import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED;
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_KEYGUARD;
+import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_SYSTEM_ERROR;
import static com.android.server.wm.WindowManagerService.DEBUG_KEYGUARD;
import static com.android.server.wm.WindowManagerService.LayoutFields.SET_UPDATE_ROTATION;
import static com.android.server.wm.WindowManagerService.LayoutFields.SET_WALLPAPER_MAY_CHANGE;
@@ -330,7 +331,9 @@
+ " anim=" + win.mWinAnimator.mAnimation);
} else if (mPolicy.canBeForceHidden(win, win.mAttrs)) {
final boolean hideWhenLocked = !((win.mIsImWindow && showImeOverKeyguard) ||
- (appShowWhenLocked != null && appShowWhenLocked == win.mAppToken));
+ (appShowWhenLocked != null && (appShowWhenLocked == win.mAppToken ||
+ // Show error dialogs over apps that dismiss keyguard.
+ (win.mAttrs.privateFlags & PRIVATE_FLAG_SYSTEM_ERROR) != 0)));
if (((mForceHiding == KEYGUARD_ANIMATING_IN)
&& (!winAnimator.isAnimating() || hideWhenLocked))
|| ((mForceHiding == KEYGUARD_SHOWN) && hideWhenLocked)) {
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 318ff0e..6cb1e4a 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -10791,9 +10791,7 @@
boolean canReceiveKeys, boolean hasFocus, boolean touchFullscreen) {
synchronized (mWindowMap) {
FakeWindowImpl fw = new FakeWindowImpl(this, looper, inputEventReceiverFactory,
- name, windowType,
- layoutParamsFlags, layoutParamsPrivateFlags, canReceiveKeys,
- hasFocus, touchFullscreen);
+ name, windowType, layoutParamsFlags, canReceiveKeys, hasFocus, touchFullscreen);
int i=0;
while (i<mFakeWindows.size()) {
if (mFakeWindows.get(i).mWindowLayer <= fw.mWindowLayer) {
diff --git a/services/core/jni/Android.mk b/services/core/jni/Android.mk
index d81cdd9..7996f73 100644
--- a/services/core/jni/Android.mk
+++ b/services/core/jni/Android.mk
@@ -2,7 +2,7 @@
# files
LOCAL_REL_DIR := core/jni
-LOCAL_CFLAGS += -Wno-unused-parameter
+LOCAL_CFLAGS += -Wall -Werror
LOCAL_SRC_FILES += \
$(LOCAL_REL_DIR)/com_android_server_AlarmManagerService.cpp \
diff --git a/services/core/jni/com_android_server_AssetAtlasService.cpp b/services/core/jni/com_android_server_AssetAtlasService.cpp
index 3696e24..e4f242e 100644
--- a/services/core/jni/com_android_server_AssetAtlasService.cpp
+++ b/services/core/jni/com_android_server_AssetAtlasService.cpp
@@ -29,8 +29,12 @@
#include <EGL/egl.h>
#include <EGL/eglext.h>
+// Disable warnings for Skia.
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wunused-parameter"
#include <SkCanvas.h>
#include <SkBitmap.h>
+#pragma GCC diagnostic pop
namespace android {
diff --git a/services/core/jni/com_android_server_ConsumerIrService.cpp b/services/core/jni/com_android_server_ConsumerIrService.cpp
index 3a50ff7..f5121cd 100644
--- a/services/core/jni/com_android_server_ConsumerIrService.cpp
+++ b/services/core/jni/com_android_server_ConsumerIrService.cpp
@@ -29,7 +29,7 @@
namespace android {
-static jlong halOpen(JNIEnv *env, jobject obj) {
+static jlong halOpen(JNIEnv* /* env */, jobject /* obj */) {
hw_module_t const* module;
consumerir_device_t *dev;
int err;
@@ -50,7 +50,7 @@
return reinterpret_cast<jlong>(dev);
}
-static jint halTransmit(JNIEnv *env, jobject obj, jlong halObject,
+static jint halTransmit(JNIEnv *env, jobject /* obj */, jlong halObject,
jint carrierFrequency, jintArray pattern) {
int ret;
@@ -66,7 +66,7 @@
return reinterpret_cast<jint>(ret);
}
-static jintArray halGetCarrierFrequencies(JNIEnv *env, jobject obj,
+static jintArray halGetCarrierFrequencies(JNIEnv *env, jobject /* obj */,
jlong halObject) {
consumerir_device_t *dev = reinterpret_cast<consumerir_device_t*>(halObject);
consumerir_freq_range_t *ranges;
diff --git a/services/core/jni/com_android_server_SerialService.cpp b/services/core/jni/com_android_server_SerialService.cpp
index b889b78..d48d159 100644
--- a/services/core/jni/com_android_server_SerialService.cpp
+++ b/services/core/jni/com_android_server_SerialService.cpp
@@ -34,7 +34,7 @@
jmethodID mConstructor;
} gParcelFileDescriptorOffsets;
-static jobject android_server_SerialService_open(JNIEnv *env, jobject thiz, jstring path)
+static jobject android_server_SerialService_open(JNIEnv *env, jobject /* thiz */, jstring path)
{
const char *pathStr = env->GetStringUTFChars(path, NULL);
diff --git a/services/core/jni/com_android_server_SystemServer.cpp b/services/core/jni/com_android_server_SystemServer.cpp
index 0625544..c50d63c 100644
--- a/services/core/jni/com_android_server_SystemServer.cpp
+++ b/services/core/jni/com_android_server_SystemServer.cpp
@@ -25,7 +25,7 @@
namespace android {
-static void android_server_SystemServer_nativeInit(JNIEnv* env, jobject clazz) {
+static void android_server_SystemServer_nativeInit(JNIEnv* /* env */, jobject /* clazz */) {
char propBuf[PROPERTY_VALUE_MAX];
property_get("system_init.startsensorservice", propBuf, "1");
if (strcmp(propBuf, "1") == 0) {
diff --git a/services/core/jni/com_android_server_UsbDeviceManager.cpp b/services/core/jni/com_android_server_UsbDeviceManager.cpp
index 3551733..8d1a338 100644
--- a/services/core/jni/com_android_server_UsbDeviceManager.cpp
+++ b/services/core/jni/com_android_server_UsbDeviceManager.cpp
@@ -63,7 +63,8 @@
}
-static jobjectArray android_server_UsbDeviceManager_getAccessoryStrings(JNIEnv *env, jobject thiz)
+static jobjectArray android_server_UsbDeviceManager_getAccessoryStrings(JNIEnv *env,
+ jobject /* thiz */)
{
int fd = open(DRIVER_NAME, O_RDWR);
if (fd < 0) {
@@ -85,7 +86,7 @@
return strArray;
}
-static jobject android_server_UsbDeviceManager_openAccessory(JNIEnv *env, jobject thiz)
+static jobject android_server_UsbDeviceManager_openAccessory(JNIEnv *env, jobject /* thiz */)
{
int fd = open(DRIVER_NAME, O_RDWR);
if (fd < 0) {
@@ -100,7 +101,8 @@
gParcelFileDescriptorOffsets.mConstructor, fileDescriptor);
}
-static jboolean android_server_UsbDeviceManager_isStartRequested(JNIEnv *env, jobject thiz)
+static jboolean android_server_UsbDeviceManager_isStartRequested(JNIEnv* /* env */,
+ jobject /* thiz */)
{
int fd = open(DRIVER_NAME, O_RDWR);
if (fd < 0) {
@@ -112,7 +114,7 @@
return (result == 1);
}
-static jint android_server_UsbDeviceManager_getAudioMode(JNIEnv *env, jobject thiz)
+static jint android_server_UsbDeviceManager_getAudioMode(JNIEnv* /* env */, jobject /* thiz */)
{
int fd = open(DRIVER_NAME, O_RDWR);
if (fd < 0) {
diff --git a/services/core/jni/com_android_server_UsbHostManager.cpp b/services/core/jni/com_android_server_UsbHostManager.cpp
index 32c3f95..ee50ff9 100644
--- a/services/core/jni/com_android_server_UsbHostManager.cpp
+++ b/services/core/jni/com_android_server_UsbHostManager.cpp
@@ -148,7 +148,7 @@
return 0;
}
-static void android_server_UsbHostManager_monitorUsbHostBus(JNIEnv *env, jobject thiz)
+static void android_server_UsbHostManager_monitorUsbHostBus(JNIEnv* /* env */, jobject thiz)
{
struct usb_host_context* context = usb_host_init();
if (!context) {
@@ -159,7 +159,8 @@
usb_host_run(context, usb_device_added, usb_device_removed, NULL, (void *)thiz);
}
-static jobject android_server_UsbHostManager_openDevice(JNIEnv *env, jobject thiz, jstring deviceName)
+static jobject android_server_UsbHostManager_openDevice(JNIEnv *env, jobject /* thiz */,
+ jstring deviceName)
{
const char *deviceNameStr = env->GetStringUTFChars(deviceName, NULL);
struct usb_device* device = usb_device_open(deviceNameStr);
diff --git a/services/core/jni/com_android_server_VibratorService.cpp b/services/core/jni/com_android_server_VibratorService.cpp
index 2b3f74a..fb1166b 100644
--- a/services/core/jni/com_android_server_VibratorService.cpp
+++ b/services/core/jni/com_android_server_VibratorService.cpp
@@ -29,18 +29,18 @@
namespace android
{
-static jboolean vibratorExists(JNIEnv *env, jobject clazz)
+static jboolean vibratorExists(JNIEnv* /* env */, jobject /* clazz */)
{
return vibrator_exists() > 0 ? JNI_TRUE : JNI_FALSE;
}
-static void vibratorOn(JNIEnv *env, jobject clazz, jlong timeout_ms)
+static void vibratorOn(JNIEnv* /* env */, jobject /* clazz */, jlong timeout_ms)
{
// ALOGI("vibratorOn\n");
vibrator_on(timeout_ms);
}
-static void vibratorOff(JNIEnv *env, jobject clazz)
+static void vibratorOff(JNIEnv* /* env */, jobject /* clazz */)
{
// ALOGI("vibratorOff\n");
vibrator_off();
diff --git a/services/core/jni/com_android_server_connectivity_Vpn.cpp b/services/core/jni/com_android_server_connectivity_Vpn.cpp
index 2a16dfe..7faeb49 100644
--- a/services/core/jni/com_android_server_connectivity_Vpn.cpp
+++ b/services/core/jni/com_android_server_connectivity_Vpn.cpp
@@ -226,12 +226,12 @@
jniThrowNullPointerException(env, "address");
} else {
if (add) {
- if (error = ifc_add_address(name, address, jPrefixLength)) {
+ if ((error = ifc_add_address(name, address, jPrefixLength)) != 0) {
ALOGE("Cannot add address %s/%d on interface %s (%s)", address, jPrefixLength, name,
strerror(-error));
}
} else {
- if (error = ifc_del_address(name, address, jPrefixLength)) {
+ if ((error = ifc_del_address(name, address, jPrefixLength)) != 0) {
ALOGE("Cannot del address %s/%d on interface %s (%s)", address, jPrefixLength, name,
strerror(-error));
}
@@ -258,7 +258,7 @@
}
}
-static jint create(JNIEnv *env, jobject thiz, jint mtu)
+static jint create(JNIEnv *env, jobject /* thiz */, jint mtu)
{
int tun = create_interface(mtu);
if (tun < 0) {
@@ -268,7 +268,7 @@
return tun;
}
-static jstring getName(JNIEnv *env, jobject thiz, jint tun)
+static jstring getName(JNIEnv *env, jobject /* thiz */, jint tun)
{
char name[IFNAMSIZ];
if (get_interface_name(name, tun) < 0) {
@@ -278,7 +278,7 @@
return env->NewStringUTF(name);
}
-static jint setAddresses(JNIEnv *env, jobject thiz, jstring jName,
+static jint setAddresses(JNIEnv *env, jobject /* thiz */, jstring jName,
jstring jAddresses)
{
const char *name = NULL;
@@ -311,7 +311,7 @@
return count;
}
-static void reset(JNIEnv *env, jobject thiz, jstring jName)
+static void reset(JNIEnv *env, jobject /* thiz */, jstring jName)
{
const char *name = jName ? env->GetStringUTFChars(jName, NULL) : NULL;
if (!name) {
@@ -324,7 +324,7 @@
env->ReleaseStringUTFChars(jName, name);
}
-static jint check(JNIEnv *env, jobject thiz, jstring jName)
+static jint check(JNIEnv *env, jobject /* thiz */, jstring jName)
{
const char *name = jName ? env->GetStringUTFChars(jName, NULL) : NULL;
if (!name) {
diff --git a/services/core/jni/com_android_server_input_InputManagerService.cpp b/services/core/jni/com_android_server_input_InputManagerService.cpp
index cddca92..5d73af8 100644
--- a/services/core/jni/com_android_server_input_InputManagerService.cpp
+++ b/services/core/jni/com_android_server_input_InputManagerService.cpp
@@ -350,14 +350,14 @@
}
}
-status_t NativeInputManager::registerInputChannel(JNIEnv* env,
+status_t NativeInputManager::registerInputChannel(JNIEnv* /* env */,
const sp<InputChannel>& inputChannel,
const sp<InputWindowHandle>& inputWindowHandle, bool monitor) {
return mInputManager->getDispatcher()->registerInputChannel(
inputChannel, inputWindowHandle, monitor);
}
-status_t NativeInputManager::unregisterInputChannel(JNIEnv* env,
+status_t NativeInputManager::unregisterInputChannel(JNIEnv* /* env */,
const sp<InputChannel>& inputChannel) {
return mInputManager->getDispatcher()->unregisterInputChannel(inputChannel);
}
@@ -428,7 +428,7 @@
} // release lock
}
-sp<PointerControllerInterface> NativeInputManager::obtainPointerController(int32_t deviceId) {
+sp<PointerControllerInterface> NativeInputManager::obtainPointerController(int32_t /* deviceId */) {
AutoMutex _l(mLock);
sp<PointerController> controller = mLocked.pointerController.promote();
@@ -548,7 +548,7 @@
}
void NativeInputManager::notifySwitch(nsecs_t when,
- uint32_t switchValues, uint32_t switchMask, uint32_t policyFlags) {
+ uint32_t switchValues, uint32_t switchMask, uint32_t /* policyFlags */) {
#if DEBUG_INPUT_DISPATCHER_POLICY
ALOGD("notifySwitch - when=%lld, switchValues=0x%08x, switchMask=0x%08x, policyFlags=0x%x",
when, switchValues, switchMask, policyFlags);
@@ -1006,7 +1006,7 @@
// ----------------------------------------------------------------------------
-static jlong nativeInit(JNIEnv* env, jclass clazz,
+static jlong nativeInit(JNIEnv* env, jclass /* clazz */,
jobject serviceObj, jobject contextObj, jobject messageQueueObj) {
sp<MessageQueue> messageQueue = android_os_MessageQueue_getMessageQueue(env, messageQueueObj);
if (messageQueue == NULL) {
@@ -1020,7 +1020,7 @@
return reinterpret_cast<jlong>(im);
}
-static void nativeStart(JNIEnv* env, jclass clazz, jlong ptr) {
+static void nativeStart(JNIEnv* env, jclass /* clazz */, jlong ptr) {
NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
status_t result = im->getInputManager()->start();
@@ -1029,8 +1029,8 @@
}
}
-static void nativeSetDisplayViewport(JNIEnv* env, jclass clazz, jlong ptr, jboolean external,
- jint displayId, jint orientation,
+static void nativeSetDisplayViewport(JNIEnv* /* env */, jclass /* clazz */, jlong ptr,
+ jboolean external, jint displayId, jint orientation,
jint logicalLeft, jint logicalTop, jint logicalRight, jint logicalBottom,
jint physicalLeft, jint physicalTop, jint physicalRight, jint physicalBottom,
jint deviceWidth, jint deviceHeight) {
@@ -1052,7 +1052,7 @@
im->setDisplayViewport(external, v);
}
-static jint nativeGetScanCodeState(JNIEnv* env, jclass clazz,
+static jint nativeGetScanCodeState(JNIEnv* /* env */, jclass /* clazz */,
jlong ptr, jint deviceId, jint sourceMask, jint scanCode) {
NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
@@ -1060,7 +1060,7 @@
deviceId, uint32_t(sourceMask), scanCode);
}
-static jint nativeGetKeyCodeState(JNIEnv* env, jclass clazz,
+static jint nativeGetKeyCodeState(JNIEnv* /* env */, jclass /* clazz */,
jlong ptr, jint deviceId, jint sourceMask, jint keyCode) {
NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
@@ -1068,7 +1068,7 @@
deviceId, uint32_t(sourceMask), keyCode);
}
-static jint nativeGetSwitchState(JNIEnv* env, jclass clazz,
+static jint nativeGetSwitchState(JNIEnv* /* env */, jclass /* clazz */,
jlong ptr, jint deviceId, jint sourceMask, jint sw) {
NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
@@ -1076,7 +1076,7 @@
deviceId, uint32_t(sourceMask), sw);
}
-static jboolean nativeHasKeys(JNIEnv* env, jclass clazz,
+static jboolean nativeHasKeys(JNIEnv* env, jclass /* clazz */,
jlong ptr, jint deviceId, jint sourceMask, jintArray keyCodes, jbooleanArray outFlags) {
NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
@@ -1106,7 +1106,7 @@
}
static void handleInputChannelDisposed(JNIEnv* env,
- jobject inputChannelObj, const sp<InputChannel>& inputChannel, void* data) {
+ jobject /* inputChannelObj */, const sp<InputChannel>& inputChannel, void* data) {
NativeInputManager* im = static_cast<NativeInputManager*>(data);
ALOGW("Input channel object '%s' was disposed without first being unregistered with "
@@ -1114,7 +1114,7 @@
im->unregisterInputChannel(env, inputChannel);
}
-static void nativeRegisterInputChannel(JNIEnv* env, jclass clazz,
+static void nativeRegisterInputChannel(JNIEnv* env, jclass /* clazz */,
jlong ptr, jobject inputChannelObj, jobject inputWindowHandleObj, jboolean monitor) {
NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
@@ -1143,7 +1143,7 @@
}
}
-static void nativeUnregisterInputChannel(JNIEnv* env, jclass clazz,
+static void nativeUnregisterInputChannel(JNIEnv* env, jclass /* clazz */,
jlong ptr, jobject inputChannelObj) {
NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
@@ -1164,14 +1164,14 @@
}
}
-static void nativeSetInputFilterEnabled(JNIEnv* env, jclass clazz,
+static void nativeSetInputFilterEnabled(JNIEnv* /* env */, jclass /* clazz */,
jlong ptr, jboolean enabled) {
NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
im->getInputManager()->getDispatcher()->setInputFilterEnabled(enabled);
}
-static jint nativeInjectInputEvent(JNIEnv* env, jclass clazz,
+static jint nativeInjectInputEvent(JNIEnv* env, jclass /* clazz */,
jlong ptr, jobject inputEventObj, jint displayId, jint injectorPid, jint injectorUid,
jint syncMode, jint timeoutMillis, jint policyFlags) {
NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
@@ -1203,36 +1203,36 @@
}
}
-static void nativeSetInputWindows(JNIEnv* env, jclass clazz,
+static void nativeSetInputWindows(JNIEnv* env, jclass /* clazz */,
jlong ptr, jobjectArray windowHandleObjArray) {
NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
im->setInputWindows(env, windowHandleObjArray);
}
-static void nativeSetFocusedApplication(JNIEnv* env, jclass clazz,
+static void nativeSetFocusedApplication(JNIEnv* env, jclass /* clazz */,
jlong ptr, jobject applicationHandleObj) {
NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
im->setFocusedApplication(env, applicationHandleObj);
}
-static void nativeSetInputDispatchMode(JNIEnv* env,
- jclass clazz, jlong ptr, jboolean enabled, jboolean frozen) {
+static void nativeSetInputDispatchMode(JNIEnv* /* env */,
+ jclass /* clazz */, jlong ptr, jboolean enabled, jboolean frozen) {
NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
im->setInputDispatchMode(enabled, frozen);
}
-static void nativeSetSystemUiVisibility(JNIEnv* env,
- jclass clazz, jlong ptr, jint visibility) {
+static void nativeSetSystemUiVisibility(JNIEnv* /* env */,
+ jclass /* clazz */, jlong ptr, jint visibility) {
NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
im->setSystemUiVisibility(visibility);
}
static jboolean nativeTransferTouchFocus(JNIEnv* env,
- jclass clazz, jlong ptr, jobject fromChannelObj, jobject toChannelObj) {
+ jclass /* clazz */, jlong ptr, jobject fromChannelObj, jobject toChannelObj) {
NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
sp<InputChannel> fromChannel =
@@ -1252,15 +1252,15 @@
}
}
-static void nativeSetPointerSpeed(JNIEnv* env,
- jclass clazz, jlong ptr, jint speed) {
+static void nativeSetPointerSpeed(JNIEnv* /* env */,
+ jclass /* clazz */, jlong ptr, jint speed) {
NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
im->setPointerSpeed(speed);
}
-static void nativeSetShowTouches(JNIEnv* env,
- jclass clazz, jlong ptr, jboolean enabled) {
+static void nativeSetShowTouches(JNIEnv* /* env */,
+ jclass /* clazz */, jlong ptr, jboolean enabled) {
NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
im->setShowTouches(enabled);
@@ -1279,7 +1279,7 @@
}
static void nativeVibrate(JNIEnv* env,
- jclass clazz, jlong ptr, jint deviceId, jlongArray patternObj,
+ jclass /* clazz */, jlong ptr, jint deviceId, jlongArray patternObj,
jint repeat, jint token) {
NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
@@ -1303,30 +1303,30 @@
im->getInputManager()->getReader()->vibrate(deviceId, pattern, patternSize, repeat, token);
}
-static void nativeCancelVibrate(JNIEnv* env,
- jclass clazz, jlong ptr, jint deviceId, jint token) {
+static void nativeCancelVibrate(JNIEnv* /* env */,
+ jclass /* clazz */, jlong ptr, jint deviceId, jint token) {
NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
im->getInputManager()->getReader()->cancelVibrate(deviceId, token);
}
-static void nativeReloadKeyboardLayouts(JNIEnv* env,
- jclass clazz, jlong ptr) {
+static void nativeReloadKeyboardLayouts(JNIEnv* /* env */,
+ jclass /* clazz */, jlong ptr) {
NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
im->getInputManager()->getReader()->requestRefreshConfiguration(
InputReaderConfiguration::CHANGE_KEYBOARD_LAYOUTS);
}
-static void nativeReloadDeviceAliases(JNIEnv* env,
- jclass clazz, jlong ptr) {
+static void nativeReloadDeviceAliases(JNIEnv* /* env */,
+ jclass /* clazz */, jlong ptr) {
NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
im->getInputManager()->getReader()->requestRefreshConfiguration(
InputReaderConfiguration::CHANGE_DEVICE_ALIAS);
}
-static jstring nativeDump(JNIEnv* env, jclass clazz, jlong ptr) {
+static jstring nativeDump(JNIEnv* env, jclass /* clazz */, jlong ptr) {
NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
String8 dump;
@@ -1334,7 +1334,7 @@
return env->NewStringUTF(dump.string());
}
-static void nativeMonitor(JNIEnv* env, jclass clazz, jlong ptr) {
+static void nativeMonitor(JNIEnv* /* env */, jclass /* clazz */, jlong ptr) {
NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
im->getInputManager()->getReader()->monitor();
diff --git a/services/core/jni/com_android_server_input_InputWindowHandle.cpp b/services/core/jni/com_android_server_input_InputWindowHandle.cpp
index 03bf7eb..46ec1f4 100644
--- a/services/core/jni/com_android_server_input_InputWindowHandle.cpp
+++ b/services/core/jni/com_android_server_input_InputWindowHandle.cpp
@@ -36,7 +36,6 @@
jfieldID inputChannel;
jfieldID name;
jfieldID layoutParamsFlags;
- jfieldID layoutParamsPrivateFlags;
jfieldID layoutParamsType;
jfieldID dispatchingTimeoutNanos;
jfieldID frameLeft;
@@ -113,8 +112,6 @@
mInfo->layoutParamsFlags = env->GetIntField(obj,
gInputWindowHandleClassInfo.layoutParamsFlags);
- mInfo->layoutParamsPrivateFlags = env->GetIntField(obj,
- gInputWindowHandleClassInfo.layoutParamsPrivateFlags);
mInfo->layoutParamsType = env->GetIntField(obj,
gInputWindowHandleClassInfo.layoutParamsType);
mInfo->dispatchingTimeout = env->GetLongField(obj,
@@ -251,9 +248,6 @@
GET_FIELD_ID(gInputWindowHandleClassInfo.layoutParamsFlags, clazz,
"layoutParamsFlags", "I");
- GET_FIELD_ID(gInputWindowHandleClassInfo.layoutParamsPrivateFlags, clazz,
- "layoutParamsPrivateFlags", "I");
-
GET_FIELD_ID(gInputWindowHandleClassInfo.layoutParamsType, clazz,
"layoutParamsType", "I");
diff --git a/services/core/jni/com_android_server_lights_LightsService.cpp b/services/core/jni/com_android_server_lights_LightsService.cpp
index d51e044..b2b2783 100644
--- a/services/core/jni/com_android_server_lights_LightsService.cpp
+++ b/services/core/jni/com_android_server_lights_LightsService.cpp
@@ -60,7 +60,7 @@
}
}
-static jlong init_native(JNIEnv *env, jobject clazz)
+static jlong init_native(JNIEnv* /* env */, jobject /* clazz */)
{
int err;
hw_module_t* module;
@@ -93,7 +93,7 @@
return (jlong)devices;
}
-static void finalize_native(JNIEnv *env, jobject clazz, jlong ptr)
+static void finalize_native(JNIEnv* /* env */, jobject /* clazz */, jlong ptr)
{
Devices* devices = (Devices*)ptr;
if (devices == NULL) {
@@ -103,7 +103,7 @@
free(devices);
}
-static void setLight_native(JNIEnv *env, jobject clazz, jlong ptr,
+static void setLight_native(JNIEnv* /* env */, jobject /* clazz */, jlong ptr,
jint light, jint colorARGB, jint flashMode, jint onMS, jint offMS, jint brightnessMode)
{
Devices* devices = (Devices*)ptr;
diff --git a/services/core/jni/com_android_server_location_FlpHardwareProvider.cpp b/services/core/jni/com_android_server_location_FlpHardwareProvider.cpp
index 37a3eaa..049e455 100644
--- a/services/core/jni/com_android_server_location_FlpHardwareProvider.cpp
+++ b/services/core/jni/com_android_server_location_FlpHardwareProvider.cpp
@@ -698,14 +698,14 @@
// TODO: inject any device context if when needed
}
-static jboolean IsSupported(JNIEnv* env, jclass clazz) {
+static jboolean IsSupported(JNIEnv* /* env */, jclass /* clazz */) {
if (sFlpInterface == NULL) {
return JNI_FALSE;
}
return JNI_TRUE;
}
-static jint GetBatchSize(JNIEnv* env, jobject object) {
+static jint GetBatchSize(JNIEnv* env, jobject /* object */) {
if(sFlpInterface == NULL) {
ThrowOnError(env, FLP_RESULT_ERROR, __FUNCTION__);
}
@@ -715,7 +715,7 @@
static void StartBatching(
JNIEnv* env,
- jobject object,
+ jobject /* object */,
jint id,
jobject optionsObject) {
if(sFlpInterface == NULL || optionsObject == NULL) {
@@ -730,7 +730,7 @@
static void UpdateBatchingOptions(
JNIEnv* env,
- jobject object,
+ jobject /* object */,
jint id,
jobject optionsObject) {
if(sFlpInterface == NULL || optionsObject == NULL) {
@@ -743,7 +743,7 @@
ThrowOnError(env, result, __FUNCTION__);
}
-static void StopBatching(JNIEnv* env, jobject object, jint id) {
+static void StopBatching(JNIEnv* env, jobject /* object */, jint id) {
if(sFlpInterface == NULL) {
ThrowOnError(env, FLP_RESULT_ERROR, __FUNCTION__);
}
@@ -751,7 +751,7 @@
sFlpInterface->stop_batching(id);
}
-static void Cleanup(JNIEnv* env, jobject object) {
+static void Cleanup(JNIEnv* env, jobject /* object */) {
if(sFlpInterface == NULL) {
ThrowOnError(env, FLP_RESULT_ERROR, __FUNCTION__);
}
@@ -774,7 +774,7 @@
}
}
-static void GetBatchedLocation(JNIEnv* env, jobject object, jint lastNLocations) {
+static void GetBatchedLocation(JNIEnv* env, jobject /* object */, jint lastNLocations) {
if(sFlpInterface == NULL) {
ThrowOnError(env, FLP_RESULT_ERROR, __FUNCTION__);
}
@@ -782,7 +782,7 @@
sFlpInterface->get_batched_location(lastNLocations);
}
-static void InjectLocation(JNIEnv* env, jobject object, jobject locationObject) {
+static void InjectLocation(JNIEnv* env, jobject /* object */, jobject locationObject) {
if(locationObject == NULL) {
ALOGE("Invalid location for injection: %p", locationObject);
ThrowOnError(env, FLP_RESULT_ERROR, __FUNCTION__);
@@ -806,7 +806,7 @@
return sFlpDiagnosticInterface != NULL;
}
-static void InjectDiagnosticData(JNIEnv* env, jobject object, jstring stringData) {
+static void InjectDiagnosticData(JNIEnv* env, jobject /* object */, jstring stringData) {
if(stringData == NULL) {
ALOGE("Invalid diagnostic data for injection: %p", stringData);
ThrowOnError(env, FLP_RESULT_ERROR, __FUNCTION__);
@@ -830,7 +830,7 @@
return sFlpDeviceContextInterface != NULL;
}
-static void InjectDeviceContext(JNIEnv* env, jobject object, jint enabledMask) {
+static void InjectDeviceContext(JNIEnv* env, jobject /* object */, jint enabledMask) {
if(sFlpDeviceContextInterface == NULL) {
ThrowOnError(env, FLP_RESULT_ERROR, __FUNCTION__);
}
@@ -845,7 +845,7 @@
static void AddGeofences(
JNIEnv* env,
- jobject object,
+ jobject /* object */,
jobjectArray geofenceRequestsArray) {
if(geofenceRequestsArray == NULL) {
ALOGE("Invalid Geofences to add: %p", geofenceRequestsArray);
@@ -885,7 +885,7 @@
}
}
-static void PauseGeofence(JNIEnv* env, jobject object, jint geofenceId) {
+static void PauseGeofence(JNIEnv* env, jobject /* object */, jint geofenceId) {
if(sFlpGeofencingInterface == NULL) {
ThrowOnError(env, FLP_RESULT_ERROR, __FUNCTION__);
}
@@ -895,7 +895,7 @@
static void ResumeGeofence(
JNIEnv* env,
- jobject object,
+ jobject /* object */,
jint geofenceId,
jint monitorTransitions) {
if(sFlpGeofencingInterface == NULL) {
@@ -907,7 +907,7 @@
static void ModifyGeofenceOption(
JNIEnv* env,
- jobject object,
+ jobject /* object */,
jint geofenceId,
jint lastTransition,
jint monitorTransitions,
@@ -931,7 +931,7 @@
static void RemoveGeofences(
JNIEnv* env,
- jobject object,
+ jobject /* object */,
jintArray geofenceIdsArray) {
if(sFlpGeofencingInterface == NULL) {
ThrowOnError(env, FLP_RESULT_ERROR, __FUNCTION__);
diff --git a/services/core/jni/com_android_server_location_GpsLocationProvider.cpp b/services/core/jni/com_android_server_location_GpsLocationProvider.cpp
index 8183321..84482bc 100644
--- a/services/core/jni/com_android_server_location_GpsLocationProvider.cpp
+++ b/services/core/jni/com_android_server_location_GpsLocationProvider.cpp
@@ -509,7 +509,8 @@
}
}
-static jboolean android_location_GpsLocationProvider_is_supported(JNIEnv* env, jclass clazz) {
+static jboolean android_location_GpsLocationProvider_is_supported(JNIEnv* /* env */,
+ jclass /* clazz */) {
if (sGpsInterface != NULL) {
return JNI_TRUE;
} else {
@@ -543,14 +544,15 @@
return JNI_TRUE;
}
-static void android_location_GpsLocationProvider_cleanup(JNIEnv* env, jobject obj)
+static void android_location_GpsLocationProvider_cleanup(JNIEnv* /* env */, jobject /* obj */)
{
if (sGpsInterface)
sGpsInterface->cleanup();
}
-static jboolean android_location_GpsLocationProvider_set_position_mode(JNIEnv* env, jobject obj,
- jint mode, jint recurrence, jint min_interval, jint preferred_accuracy, jint preferred_time)
+static jboolean android_location_GpsLocationProvider_set_position_mode(JNIEnv* /* env */,
+ jobject /* obj */, jint mode, jint recurrence, jint min_interval, jint preferred_accuracy,
+ jint preferred_time)
{
if (sGpsInterface) {
if (sGpsInterface->set_position_mode(mode, recurrence, min_interval, preferred_accuracy,
@@ -564,7 +566,7 @@
return JNI_FALSE;
}
-static jboolean android_location_GpsLocationProvider_start(JNIEnv* env, jobject obj)
+static jboolean android_location_GpsLocationProvider_start(JNIEnv* /* env */, jobject /* obj */)
{
if (sGpsInterface) {
if (sGpsInterface->start() == 0) {
@@ -577,7 +579,7 @@
return JNI_FALSE;
}
-static jboolean android_location_GpsLocationProvider_stop(JNIEnv* env, jobject obj)
+static jboolean android_location_GpsLocationProvider_stop(JNIEnv* /* env */, jobject /* obj */)
{
if (sGpsInterface) {
if (sGpsInterface->stop() == 0) {
@@ -590,13 +592,15 @@
return JNI_FALSE;
}
-static void android_location_GpsLocationProvider_delete_aiding_data(JNIEnv* env, jobject obj, jint flags)
+static void android_location_GpsLocationProvider_delete_aiding_data(JNIEnv* /* env */,
+ jobject /* obj */,
+ jint flags)
{
if (sGpsInterface)
sGpsInterface->delete_aiding_data(flags);
}
-static jint android_location_GpsLocationProvider_read_sv_status(JNIEnv* env, jobject obj,
+static jint android_location_GpsLocationProvider_read_sv_status(JNIEnv* env, jobject /* obj */,
jintArray prnArray, jfloatArray snrArray, jfloatArray elevArray, jfloatArray azumArray,
jintArray maskArray)
{
@@ -627,8 +631,8 @@
return (jint) num_svs;
}
-static void android_location_GpsLocationProvider_agps_set_reference_location_cellid(JNIEnv* env,
- jobject obj, jint type, jint mcc, jint mnc, jint lac, jint cid)
+static void android_location_GpsLocationProvider_agps_set_reference_location_cellid(
+ JNIEnv* /* env */, jobject /* obj */, jint type, jint mcc, jint mnc, jint lac, jint cid)
{
AGpsRefLocation location;
@@ -655,7 +659,7 @@
}
static void android_location_GpsLocationProvider_agps_send_ni_message(JNIEnv* env,
- jobject obj, jbyteArray ni_msg, jint size)
+ jobject /* obj */, jbyteArray ni_msg, jint size)
{
size_t sz;
@@ -671,8 +675,8 @@
env->ReleaseByteArrayElements(ni_msg,b,0);
}
-static void android_location_GpsLocationProvider_agps_set_id(JNIEnv *env,
- jobject obj, jint type, jstring setid_string)
+static void android_location_GpsLocationProvider_agps_set_id(JNIEnv *env, jobject /* obj */,
+ jint type, jstring setid_string)
{
if (!sAGpsRilInterface) {
ALOGE("no AGPS RIL interface in agps_set_id");
@@ -684,7 +688,7 @@
env->ReleaseStringUTFChars(setid_string, setid);
}
-static jint android_location_GpsLocationProvider_read_nmea(JNIEnv* env, jobject obj,
+static jint android_location_GpsLocationProvider_read_nmea(JNIEnv* env, jobject /* obj */,
jbyteArray nmeaArray, jint buffer_size)
{
// this should only be called from within a call to reportNmea
@@ -697,21 +701,22 @@
return (jint) length;
}
-static void android_location_GpsLocationProvider_inject_time(JNIEnv* env, jobject obj,
+static void android_location_GpsLocationProvider_inject_time(JNIEnv* /* env */, jobject /* obj */,
jlong time, jlong timeReference, jint uncertainty)
{
if (sGpsInterface)
sGpsInterface->inject_time(time, timeReference, uncertainty);
}
-static void android_location_GpsLocationProvider_inject_location(JNIEnv* env, jobject obj,
- jdouble latitude, jdouble longitude, jfloat accuracy)
+static void android_location_GpsLocationProvider_inject_location(JNIEnv* /* env */,
+ jobject /* obj */, jdouble latitude, jdouble longitude, jfloat accuracy)
{
if (sGpsInterface)
sGpsInterface->inject_location(latitude, longitude, accuracy);
}
-static jboolean android_location_GpsLocationProvider_supports_xtra(JNIEnv* env, jobject obj)
+static jboolean android_location_GpsLocationProvider_supports_xtra(JNIEnv* /* env */,
+ jobject /* obj */)
{
if (sGpsXtraInterface != NULL) {
return JNI_TRUE;
@@ -720,7 +725,7 @@
}
}
-static void android_location_GpsLocationProvider_inject_xtra_data(JNIEnv* env, jobject obj,
+static void android_location_GpsLocationProvider_inject_xtra_data(JNIEnv* env, jobject /* obj */,
jbyteArray data, jint length)
{
if (!sGpsXtraInterface) {
@@ -734,7 +739,7 @@
}
static void android_location_GpsLocationProvider_agps_data_conn_open(
- JNIEnv* env, jobject obj, jstring apn, jint apnIpType)
+ JNIEnv* env, jobject /* obj */, jstring apn, jint apnIpType)
{
if (!sAGpsInterface) {
ALOGE("no AGPS interface in agps_data_conn_open");
@@ -759,7 +764,8 @@
env->ReleaseStringUTFChars(apn, apnStr);
}
-static void android_location_GpsLocationProvider_agps_data_conn_closed(JNIEnv* env, jobject obj)
+static void android_location_GpsLocationProvider_agps_data_conn_closed(JNIEnv* /* env */,
+ jobject /* obj */)
{
if (!sAGpsInterface) {
ALOGE("no AGPS interface in agps_data_conn_closed");
@@ -768,7 +774,8 @@
sAGpsInterface->data_conn_closed();
}
-static void android_location_GpsLocationProvider_agps_data_conn_failed(JNIEnv* env, jobject obj)
+static void android_location_GpsLocationProvider_agps_data_conn_failed(JNIEnv* /* env */,
+ jobject /* obj */)
{
if (!sAGpsInterface) {
ALOGE("no AGPS interface in agps_data_conn_failed");
@@ -777,7 +784,7 @@
sAGpsInterface->data_conn_failed();
}
-static void android_location_GpsLocationProvider_set_agps_server(JNIEnv* env, jobject obj,
+static void android_location_GpsLocationProvider_set_agps_server(JNIEnv* env, jobject /* obj */,
jint type, jstring hostname, jint port)
{
if (!sAGpsInterface) {
@@ -789,8 +796,8 @@
env->ReleaseStringUTFChars(hostname, c_hostname);
}
-static void android_location_GpsLocationProvider_send_ni_response(JNIEnv* env, jobject obj,
- jint notifId, jint response)
+static void android_location_GpsLocationProvider_send_ni_response(JNIEnv* /* env */,
+ jobject /* obj */, jint notifId, jint response)
{
if (!sGpsNiInterface) {
ALOGE("no NI interface in send_ni_response");
@@ -800,8 +807,8 @@
sGpsNiInterface->respond(notifId, response);
}
-static jstring android_location_GpsLocationProvider_get_internal_state(JNIEnv* env, jobject obj)
-{
+static jstring android_location_GpsLocationProvider_get_internal_state(JNIEnv* env,
+ jobject /* obj */) {
jstring result = NULL;
if (sGpsDebugInterface) {
const size_t maxLength = 2047;
@@ -814,7 +821,7 @@
return result;
}
-static void android_location_GpsLocationProvider_update_network_state(JNIEnv* env, jobject obj,
+static void android_location_GpsLocationProvider_update_network_state(JNIEnv* env, jobject /* obj */,
jboolean connected, jint type, jboolean roaming, jboolean available, jstring extraInfo, jstring apn)
{
@@ -837,16 +844,17 @@
}
}
-static jboolean android_location_GpsLocationProvider_is_geofence_supported(JNIEnv* env,
- jobject obj) {
+static jboolean android_location_GpsLocationProvider_is_geofence_supported(JNIEnv* /* env */,
+ jobject /* obj */)
+{
if (sGpsGeofencingInterface != NULL) {
return JNI_TRUE;
}
return JNI_FALSE;
}
-static jboolean android_location_GpsLocationProvider_add_geofence(JNIEnv* env, jobject obj,
- jint geofence_id, jdouble latitude, jdouble longitude, jdouble radius,
+static jboolean android_location_GpsLocationProvider_add_geofence(JNIEnv* /* env */,
+ jobject /* obj */, jint geofence_id, jdouble latitude, jdouble longitude, jdouble radius,
jint last_transition, jint monitor_transition, jint notification_responsiveness,
jint unknown_timer) {
if (sGpsGeofencingInterface != NULL) {
@@ -860,8 +868,8 @@
return JNI_FALSE;
}
-static jboolean android_location_GpsLocationProvider_remove_geofence(JNIEnv* env, jobject obj,
- jint geofence_id) {
+static jboolean android_location_GpsLocationProvider_remove_geofence(JNIEnv* /* env */,
+ jobject /* obj */, jint geofence_id) {
if (sGpsGeofencingInterface != NULL) {
sGpsGeofencingInterface->remove_geofence_area(geofence_id);
return JNI_TRUE;
@@ -871,8 +879,8 @@
return JNI_FALSE;
}
-static jboolean android_location_GpsLocationProvider_pause_geofence(JNIEnv* env, jobject obj,
- jint geofence_id) {
+static jboolean android_location_GpsLocationProvider_pause_geofence(JNIEnv* /* env */,
+ jobject /* obj */, jint geofence_id) {
if (sGpsGeofencingInterface != NULL) {
sGpsGeofencingInterface->pause_geofence(geofence_id);
return JNI_TRUE;
@@ -882,8 +890,8 @@
return JNI_FALSE;
}
-static jboolean android_location_GpsLocationProvider_resume_geofence(JNIEnv* env, jobject obj,
- jint geofence_id, jint monitor_transition) {
+static jboolean android_location_GpsLocationProvider_resume_geofence(JNIEnv* /* env */,
+ jobject /* obj */, jint geofence_id, jint monitor_transition) {
if (sGpsGeofencingInterface != NULL) {
sGpsGeofencingInterface->resume_geofence(geofence_id, monitor_transition);
return JNI_TRUE;
diff --git a/services/core/jni/com_android_server_power_PowerManagerService.cpp b/services/core/jni/com_android_server_power_PowerManagerService.cpp
index 33e0bd7..db642dd 100644
--- a/services/core/jni/com_android_server_power_PowerManagerService.cpp
+++ b/services/core/jni/com_android_server_power_PowerManagerService.cpp
@@ -112,17 +112,17 @@
}
}
-static void nativeAcquireSuspendBlocker(JNIEnv *env, jclass clazz, jstring nameStr) {
+static void nativeAcquireSuspendBlocker(JNIEnv *env, jclass /* clazz */, jstring nameStr) {
ScopedUtfChars name(env, nameStr);
acquire_wake_lock(PARTIAL_WAKE_LOCK, name.c_str());
}
-static void nativeReleaseSuspendBlocker(JNIEnv *env, jclass clazz, jstring nameStr) {
+static void nativeReleaseSuspendBlocker(JNIEnv *env, jclass /* clazz */, jstring nameStr) {
ScopedUtfChars name(env, nameStr);
release_wake_lock(name.c_str());
}
-static void nativeSetInteractive(JNIEnv *env, jclass clazz, jboolean enable) {
+static void nativeSetInteractive(JNIEnv* /* env */, jclass /* clazz */, jboolean enable) {
if (gPowerModule) {
if (enable) {
ALOGD_IF_SLOW(20, "Excessive delay in setInteractive(true) while turning screen on");
@@ -134,7 +134,7 @@
}
}
-static void nativeSetAutoSuspend(JNIEnv *env, jclass clazz, jboolean enable) {
+static void nativeSetAutoSuspend(JNIEnv* /* env */, jclass /* clazz */, jboolean enable) {
if (enable) {
ALOGD_IF_SLOW(100, "Excessive delay in autosuspend_enable() while turning screen off");
autosuspend_enable();
diff --git a/services/core/jni/onload.cpp b/services/core/jni/onload.cpp
index 7b2e408..c65b3be 100644
--- a/services/core/jni/onload.cpp
+++ b/services/core/jni/onload.cpp
@@ -46,7 +46,7 @@
using namespace android;
-extern "C" jint JNI_OnLoad(JavaVM* vm, void* reserved)
+extern "C" jint JNI_OnLoad(JavaVM* vm, void* /* reserved */)
{
JNIEnv* env = NULL;
jint result = -1;
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index 2c6a222..9c78963 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -45,6 +45,7 @@
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.ResolveInfo;
+import android.content.pm.ServiceInfo;
import android.content.pm.UserInfo;
import android.database.ContentObserver;
import android.hardware.usb.UsbManager;
@@ -59,9 +60,9 @@
import android.os.Environment;
import android.os.Handler;
import android.os.IBinder;
-import android.os.IPowerManager;
import android.os.PersistableBundle;
import android.os.PowerManager;
+import android.os.PowerManagerInternal;
import android.os.Process;
import android.os.RecoverySystem;
import android.os.RemoteCallback;
@@ -179,6 +180,7 @@
SECURE_SETTINGS_WHITELIST = new HashSet();
SECURE_SETTINGS_WHITELIST.add(Settings.Secure.DEFAULT_INPUT_METHOD);
SECURE_SETTINGS_WHITELIST.add(Settings.Secure.SKIP_FIRST_USE_HINTS);
+ SECURE_SETTINGS_WHITELIST.add(Settings.Secure.INSTALL_NON_MARKET_APPS);
SECURE_SETTINGS_DEVICEOWNER_WHITELIST = new HashSet();
SECURE_SETTINGS_DEVICEOWNER_WHITELIST.addAll(SECURE_SETTINGS_WHITELIST);
@@ -204,7 +206,9 @@
final LocalService mLocalService;
- IPowerManager mIPowerManager;
+ final PowerManager mPowerManager;
+ final PowerManagerInternal mPowerManagerInternal;
+
IWindowManager mIWindowManager;
NotificationManager mNotificationManager;
@@ -925,8 +929,9 @@
mUserManager = UserManager.get(mContext);
mHasFeature = context.getPackageManager().hasSystemFeature(
PackageManager.FEATURE_DEVICE_ADMIN);
- mWakeLock = ((PowerManager)context.getSystemService(Context.POWER_SERVICE))
- .newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "DPM");
+ mPowerManager = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
+ mPowerManagerInternal = LocalServices.getService(PowerManagerInternal.class);
+ mWakeLock = mPowerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "DPM");
mLocalService = new LocalService();
if (!mHasFeature) {
// Skip the rest of the initialization
@@ -1038,14 +1043,6 @@
}
}
- private IPowerManager getIPowerManager() {
- if (mIPowerManager == null) {
- IBinder b = ServiceManager.getService(Context.POWER_SERVICE);
- mIPowerManager = IPowerManager.Stub.asInterface(b);
- }
- return mIPowerManager;
- }
-
private IWindowManager getWindowManager() {
if (mIWindowManager == null) {
IBinder b = ServiceManager.getService(Context.WINDOW_SERVICE);
@@ -2729,12 +2726,7 @@
}
policy.mLastMaximumTimeToLock = timeMs;
-
- try {
- getIPowerManager().setMaximumScreenOffTimeoutFromDeviceAdmin((int)timeMs);
- } catch (RemoteException e) {
- Slog.w(LOG_TAG, "Failure talking with power manager", e);
- }
+ mPowerManagerInternal.setMaximumScreenOffTimeoutFromDeviceAdmin((int)timeMs);
} finally {
Binder.restoreCallingIdentity(ident);
}
@@ -2789,7 +2781,7 @@
long ident = Binder.clearCallingIdentity();
try {
// Power off the display
- getIPowerManager().goToSleep(SystemClock.uptimeMillis(),
+ mPowerManager.goToSleep(SystemClock.uptimeMillis(),
PowerManager.GO_TO_SLEEP_REASON_DEVICE_ADMIN, 0);
// Ensure the device is locked
new LockPatternUtils(mContext).requireCredentialEntry(UserHandle.USER_ALL);
@@ -4304,8 +4296,7 @@
try {
ApplicationInfo applicationInfo = pm.getApplicationInfo(enabledPackage,
PackageManager.GET_UNINSTALLED_PACKAGES, userIdToCheck);
- systemService = (applicationInfo.flags
- & ApplicationInfo.FLAG_SYSTEM) != 0;
+ systemService = (applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
} catch (RemoteException e) {
Log.i(LOG_TAG, "Can't talk to package managed", e);
}
@@ -4439,15 +4430,10 @@
IPackageManager pm = AppGlobals.getPackageManager();
if (installedServices != null) {
for (AccessibilityServiceInfo service : installedServices) {
- String packageName = service.getResolveInfo().serviceInfo.packageName;
- try {
- ApplicationInfo applicationInfo = pm.getApplicationInfo(packageName,
- PackageManager.GET_UNINSTALLED_PACKAGES, userId);
- if ((applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
- result.add(packageName);
- }
- } catch (RemoteException e) {
- Log.i(LOG_TAG, "Accessibility service in missing package", e);
+ ServiceInfo serviceInfo = service.getResolveInfo().serviceInfo;
+ ApplicationInfo applicationInfo = serviceInfo.applicationInfo;
+ if ((applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
+ result.add(serviceInfo.packageName);
}
}
}
@@ -4598,16 +4584,10 @@
IPackageManager pm = AppGlobals.getPackageManager();
if (imes != null) {
for (InputMethodInfo ime : imes) {
- String packageName = ime.getPackageName();
- try {
- ApplicationInfo applicationInfo = pm.getApplicationInfo(
- packageName, PackageManager.GET_UNINSTALLED_PACKAGES,
- userId);
- if ((applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
- result.add(packageName);
- }
- } catch (RemoteException e) {
- Log.i(LOG_TAG, "Input method for missing package", e);
+ ServiceInfo serviceInfo = ime.getServiceInfo();
+ ApplicationInfo applicationInfo = serviceInfo.applicationInfo;
+ if ((applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
+ result.add(serviceInfo.packageName);
}
}
}
@@ -4974,7 +4954,7 @@
throws RemoteException {
ApplicationInfo appInfo = pm.getApplicationInfo(packageName, GET_UNINSTALLED_PACKAGES,
userId);
- return (appInfo.flags & ApplicationInfo.FLAG_SYSTEM) > 0;
+ return (appInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
}
@Override
diff --git a/services/tests/servicestests/src/com/android/server/LockSettingsStorageTests.java b/services/tests/servicestests/src/com/android/server/LockSettingsStorageTests.java
new file mode 100644
index 0000000..bf0e75d
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/LockSettingsStorageTests.java
@@ -0,0 +1,330 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.server;
+
+import android.content.Context;
+import android.content.ContextWrapper;
+import android.content.pm.UserInfo;
+import android.database.sqlite.SQLiteDatabase;
+import android.os.FileUtils;
+import android.os.UserManager;
+import android.test.AndroidTestCase;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.concurrent.CountDownLatch;
+
+public class LockSettingsStorageTests extends AndroidTestCase {
+ LockSettingsStorage mStorage;
+ File mStorageDir;
+
+ private File mDb;
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ mStorageDir = new File(getContext().getFilesDir(), "locksettings");
+ mDb = getContext().getDatabasePath("locksettings.db");
+
+ assertTrue(mStorageDir.exists() || mStorageDir.mkdirs());
+ assertTrue(FileUtils.deleteContents(mStorageDir));
+ assertTrue(!mDb.exists() || mDb.delete());
+
+ final Context ctx = getContext();
+ setContext(new ContextWrapper(ctx) {
+ @Override
+ public Object getSystemService(String name) {
+ if (USER_SERVICE.equals(name)) {
+ return new UserManager(ctx, null) {
+ @Override
+ public UserInfo getProfileParent(int userHandle) {
+ if (userHandle == 2) {
+ // User 2 is a profile of user 1.
+ return new UserInfo(1, "name", 0);
+ }
+ if (userHandle == 3) {
+ // User 3 is a profile of user 0.
+ return new UserInfo(0, "name", 0);
+ }
+ return null;
+ }
+ };
+ }
+ return super.getSystemService(name);
+ }
+ });
+
+ mStorage = new LockSettingsStorage(getContext(), new LockSettingsStorage.Callback() {
+ @Override
+ public void initialize(SQLiteDatabase db) {
+ mStorage.writeKeyValue(db, "initializedKey", "initialValue", 0);
+ }
+ }) {
+ @Override
+ String getLockPatternFilename(int userId) {
+ return new File(mStorageDir,
+ super.getLockPatternFilename(userId).replace('/', '-')).getAbsolutePath();
+ }
+
+ @Override
+ String getLockPasswordFilename(int userId) {
+ return new File(mStorageDir,
+ super.getLockPasswordFilename(userId).replace('/', '-')).getAbsolutePath();
+ }
+ };
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+ super.tearDown();
+ mStorage.closeDatabase();
+ }
+
+ public void testKeyValue_InitializeWorked() {
+ assertEquals("initialValue", mStorage.readKeyValue("initializedKey", "default", 0));
+ mStorage.clearCache();
+ assertEquals("initialValue", mStorage.readKeyValue("initializedKey", "default", 0));
+ }
+
+ public void testKeyValue_WriteThenRead() {
+ mStorage.writeKeyValue("key", "value", 0);
+ assertEquals("value", mStorage.readKeyValue("key", "default", 0));
+ mStorage.clearCache();
+ assertEquals("value", mStorage.readKeyValue("key", "default", 0));
+ }
+
+ public void testKeyValue_DefaultValue() {
+ assertEquals("default", mStorage.readKeyValue("unititialized key", "default", 0));
+ assertEquals("default2", mStorage.readKeyValue("unititialized key", "default2", 0));
+ }
+
+ public void testKeyValue_Concurrency() {
+ final Object monitor = new Object();
+ List<Thread> threads = new ArrayList<>();
+ for (int i = 0; i < 100; i++) {
+ final int threadId = i;
+ threads.add(new Thread() {
+ @Override
+ public void run() {
+ synchronized (monitor) {
+ try {
+ monitor.wait();
+ } catch (InterruptedException e) {
+ return;
+ }
+ mStorage.writeKeyValue("key", "1 from thread " + threadId, 0);
+ mStorage.readKeyValue("key", "default", 0);
+ mStorage.writeKeyValue("key", "2 from thread " + threadId, 0);
+ mStorage.readKeyValue("key", "default", 0);
+ mStorage.writeKeyValue("key", "3 from thread " + threadId, 0);
+ mStorage.readKeyValue("key", "default", 0);
+ mStorage.writeKeyValue("key", "4 from thread " + threadId, 0);
+ mStorage.readKeyValue("key", "default", 0);
+ mStorage.writeKeyValue("key", "5 from thread " + threadId, 0);
+ mStorage.readKeyValue("key", "default", 0);
+ }
+ }
+ });
+ threads.get(i).start();
+ }
+ mStorage.writeKeyValue("key", "initalValue", 0);
+ synchronized (monitor) {
+ monitor.notifyAll();
+ }
+ for (int i = 0; i < threads.size(); i++) {
+ try {
+ threads.get(i).join();
+ } catch (InterruptedException e) {
+ }
+ }
+ assertEquals('5', mStorage.readKeyValue("key", "default", 0).charAt(0));
+ mStorage.clearCache();
+ assertEquals('5', mStorage.readKeyValue("key", "default", 0).charAt(0));
+ }
+
+ public void testKeyValue_CacheStarvedWriter() {
+ final CountDownLatch latch = new CountDownLatch(1);
+ List<Thread> threads = new ArrayList<>();
+ for (int i = 0; i < 100; i++) {
+ final int threadId = i;
+ threads.add(new Thread() {
+ @Override
+ public void run() {
+ try {
+ latch.await();
+ } catch (InterruptedException e) {
+ return;
+ }
+ if (threadId == 50) {
+ mStorage.writeKeyValue("starvedWriterKey", "value", 0);
+ } else {
+ mStorage.readKeyValue("starvedWriterKey", "default", 0);
+ }
+ }
+ });
+ threads.get(i).start();
+ }
+ latch.countDown();
+ for (int i = 0; i < threads.size(); i++) {
+ try {
+ threads.get(i).join();
+ } catch (InterruptedException e) {
+ }
+ }
+ String cached = mStorage.readKeyValue("key", "default", 0);
+ mStorage.clearCache();
+ String storage = mStorage.readKeyValue("key", "default", 0);
+ assertEquals("Cached value didn't match stored value", storage, cached);
+ }
+
+ public void testRemoveUser() {
+ mStorage.writeKeyValue("key", "value", 0);
+ mStorage.writePasswordHash(new byte[]{1}, 0);
+ mStorage.writePatternHash(new byte[]{2}, 0);
+
+ mStorage.writeKeyValue("key", "value", 1);
+ mStorage.writePasswordHash(new byte[]{1}, 1);
+ mStorage.writePatternHash(new byte[]{2}, 1);
+
+ mStorage.removeUser(0);
+
+ assertEquals("value", mStorage.readKeyValue("key", "default", 1));
+ assertEquals("default", mStorage.readKeyValue("key", "default", 0));
+ assertNotNull(mStorage.readPasswordHash(1));
+ assertNull(mStorage.readPasswordHash(0));
+ assertNotNull(mStorage.readPatternHash(1));
+ assertNull(mStorage.readPatternHash(0));
+ }
+
+ public void testPassword_Default() {
+ assertNull(mStorage.readPasswordHash(0));
+ }
+
+ public void testPassword_Write() {
+ mStorage.writePasswordHash("thepassword".getBytes(), 0);
+
+ assertArrayEquals("thepassword".getBytes(), mStorage.readPasswordHash(0));
+ mStorage.clearCache();
+ assertArrayEquals("thepassword".getBytes(), mStorage.readPasswordHash(0));
+ }
+
+ public void testPassword_WriteProfileWritesParent() {
+ mStorage.writePasswordHash("parentpasswordd".getBytes(), 1);
+ mStorage.writePasswordHash("profilepassword".getBytes(), 2);
+
+ assertArrayEquals("profilepassword".getBytes(), mStorage.readPasswordHash(1));
+ assertArrayEquals("profilepassword".getBytes(), mStorage.readPasswordHash(2));
+ mStorage.clearCache();
+ assertArrayEquals("profilepassword".getBytes(), mStorage.readPasswordHash(1));
+ assertArrayEquals("profilepassword".getBytes(), mStorage.readPasswordHash(2));
+ }
+
+ public void testPassword_WriteParentWritesProfile() {
+ mStorage.writePasswordHash("profilepassword".getBytes(), 2);
+ mStorage.writePasswordHash("parentpasswordd".getBytes(), 1);
+
+ assertArrayEquals("parentpasswordd".getBytes(), mStorage.readPasswordHash(1));
+ assertArrayEquals("parentpasswordd".getBytes(), mStorage.readPasswordHash(2));
+ mStorage.clearCache();
+ assertArrayEquals("parentpasswordd".getBytes(), mStorage.readPasswordHash(1));
+ assertArrayEquals("parentpasswordd".getBytes(), mStorage.readPasswordHash(2));
+ }
+
+ public void testPattern_Default() {
+ assertNull(mStorage.readPasswordHash(0));
+ }
+
+ public void testPattern_Write() {
+ mStorage.writePatternHash("thepattern".getBytes(), 0);
+
+ assertArrayEquals("thepattern".getBytes(), mStorage.readPatternHash(0));
+ mStorage.clearCache();
+ assertArrayEquals("thepattern".getBytes(), mStorage.readPatternHash(0));
+ }
+
+ public void testPattern_WriteProfileWritesParent() {
+ mStorage.writePatternHash("parentpatternn".getBytes(), 1);
+ mStorage.writePatternHash("profilepattern".getBytes(), 2);
+
+ assertArrayEquals("profilepattern".getBytes(), mStorage.readPatternHash(1));
+ assertArrayEquals("profilepattern".getBytes(), mStorage.readPatternHash(2));
+ mStorage.clearCache();
+ assertArrayEquals("profilepattern".getBytes(), mStorage.readPatternHash(1));
+ assertArrayEquals("profilepattern".getBytes(), mStorage.readPatternHash(2));
+ }
+
+ public void testPattern_WriteParentWritesProfile() {
+ mStorage.writePatternHash("profilepattern".getBytes(), 2);
+ mStorage.writePatternHash("parentpatternn".getBytes(), 1);
+
+ assertArrayEquals("parentpatternn".getBytes(), mStorage.readPatternHash(1));
+ assertArrayEquals("parentpatternn".getBytes(), mStorage.readPatternHash(2));
+ mStorage.clearCache();
+ assertArrayEquals("parentpatternn".getBytes(), mStorage.readPatternHash(1));
+ assertArrayEquals("parentpatternn".getBytes(), mStorage.readPatternHash(2));
+ }
+
+ public void testPrefetch() {
+ mStorage.writeKeyValue("key", "toBeFetched", 0);
+ mStorage.writePatternHash("pattern".getBytes(), 0);
+ mStorage.writePasswordHash("password".getBytes(), 0);
+
+ mStorage.clearCache();
+ mStorage.prefetchUser(0);
+
+ assertEquals("toBeFetched", mStorage.readKeyValue("key", "default", 0));
+ assertArrayEquals("pattern".getBytes(), mStorage.readPatternHash(0));
+ assertArrayEquals("password".getBytes(), mStorage.readPasswordHash(0));
+ }
+
+ public void testFileLocation_Owner() {
+ LockSettingsStorage storage = new LockSettingsStorage(getContext(), null);
+
+ assertEquals("/data/system/gesture.key", storage.getLockPatternFilename(0));
+ assertEquals("/data/system/password.key", storage.getLockPasswordFilename(0));
+ }
+
+ public void testFileLocation_SecondaryUser() {
+ LockSettingsStorage storage = new LockSettingsStorage(getContext(), null);
+
+ assertEquals("/data/system/users/1/gesture.key", storage.getLockPatternFilename(1));
+ assertEquals("/data/system/users/1/password.key", storage.getLockPasswordFilename(1));
+ }
+
+ public void testFileLocation_ProfileToSecondary() {
+ LockSettingsStorage storage = new LockSettingsStorage(getContext(), null);
+
+ assertEquals("/data/system/users/1/gesture.key", storage.getLockPatternFilename(2));
+ assertEquals("/data/system/users/1/password.key", storage.getLockPasswordFilename(2));
+ }
+
+ public void testFileLocation_ProfileToOwner() {
+ LockSettingsStorage storage = new LockSettingsStorage(getContext(), null);
+
+ assertEquals("/data/system/gesture.key", storage.getLockPatternFilename(3));
+ assertEquals("/data/system/password.key", storage.getLockPasswordFilename(3));
+ }
+
+ private static void assertArrayEquals(byte[] expected, byte[] actual) {
+ if (!Arrays.equals(expected, actual)) {
+ fail("expected:<" + Arrays.toString(expected) +
+ "> but was:<" + Arrays.toString(actual) + ">");
+ }
+ }
+}
diff --git a/telecomm/java/android/telecom/PhoneAccount.java b/telecomm/java/android/telecom/PhoneAccount.java
index f9ee5d2..a49c204f 100644
--- a/telecomm/java/android/telecom/PhoneAccount.java
+++ b/telecomm/java/android/telecom/PhoneAccount.java
@@ -124,6 +124,11 @@
*/
public static final int NO_COLOR = -1;
+ /**
+ * Indicating no resource ID is set.
+ */
+ public static final int NO_RESOURCE_ID = -1;
+
private final PhoneAccountHandle mAccountHandle;
private final Uri mAddress;
private final Uri mSubscriptionAddress;
@@ -131,7 +136,8 @@
private final int mIconResId;
private final String mIconPackageName;
private final Bitmap mIconBitmap;
- private final int mColor;
+ private final int mIconTint;
+ private final int mHighlightColor;
private final CharSequence mLabel;
private final CharSequence mShortDescription;
private final List<String> mSupportedUriSchemes;
@@ -147,7 +153,8 @@
private int mIconResId;
private String mIconPackageName;
private Bitmap mIconBitmap;
- private int mColor = NO_COLOR;
+ private int mIconTint = NO_COLOR;
+ private int mHighlightColor = NO_COLOR;
private CharSequence mLabel;
private CharSequence mShortDescription;
private List<String> mSupportedUriSchemes = new ArrayList<String>();
@@ -174,7 +181,8 @@
mIconResId = phoneAccount.getIconResId();
mIconPackageName = phoneAccount.getIconPackageName();
mIconBitmap = phoneAccount.getIconBitmap();
- mColor = phoneAccount.getColor();
+ mIconTint = phoneAccount.getIconTint();
+ mHighlightColor = phoneAccount.getHighlightColor();
mLabel = phoneAccount.getLabel();
mShortDescription = phoneAccount.getShortDescription();
mSupportedUriSchemes.addAll(phoneAccount.getSupportedUriSchemes());
@@ -214,46 +222,76 @@
}
/**
- * Sets the icon resource ID. See {@link PhoneAccount#getIconResId}.
+ * Sets the icon. See {@link PhoneAccount#createIconDrawable}.
*
- * @param value The resource ID of the icon.
+ * @param packageContext The package from which to load an icon.
+ * @param iconResId The resource in {@code iconPackageName} representing the icon.
* @return The builder.
*/
- public Builder setIconResId(int value) {
- this.mIconResId = value;
+ public Builder setIcon(Context packageContext, int iconResId) {
+ return setIcon(packageContext.getPackageName(), iconResId);
+ }
+
+ /**
+ * Sets the icon. See {@link PhoneAccount#createIconDrawable}.
+ *
+ * @param iconPackageName The package from which to load an icon.
+ * @param iconResId The resource in {@code iconPackageName} representing the icon.
+ * @return The builder.
+ */
+ public Builder setIcon(String iconPackageName, int iconResId) {
+ return setIcon(iconPackageName, iconResId, NO_COLOR);
+ }
+
+ /**
+ * Sets the icon. See {@link PhoneAccount#createIconDrawable}.
+ *
+ * @param packageContext The package from which to load an icon.
+ * @param iconResId The resource in {@code iconPackageName} representing the icon.
+ * @param iconTint A color with which to tint this icon.
+ * @return The builder.
+ */
+ public Builder setIcon(Context packageContext, int iconResId, int iconTint) {
+ return setIcon(packageContext.getPackageName(), iconResId, iconTint);
+ }
+
+ /**
+ * Sets the icon. See {@link PhoneAccount#createIconDrawable}.
+ *
+ * @param iconPackageName The package from which to load an icon.
+ * @param iconResId The resource in {@code iconPackageName} representing the icon.
+ * @param iconTint A color with which to tint this icon.
+ * @return The builder.
+ */
+ public Builder setIcon(String iconPackageName, int iconResId, int iconTint) {
+ this.mIconPackageName = iconPackageName;
+ this.mIconResId = iconResId;
+ this.mIconTint = iconTint;
return this;
}
/**
- * Sets the icon package name. See {@link PhoneAccount#getIconPackageName}.
+ * Sets the icon. See {@link PhoneAccount#createIconDrawable}.
*
- * @param value The name of the package from which to load the icon.
+ * @param iconBitmap The icon bitmap.
* @return The builder.
*/
- public Builder setIconPackageName(String value) {
- this.mIconPackageName = value;
+ public Builder setIcon(Bitmap iconBitmap) {
+ this.mIconBitmap = iconBitmap;
+ this.mIconPackageName = null;
+ this.mIconResId = NO_RESOURCE_ID;
+ this.mIconTint = NO_COLOR;
return this;
}
/**
- * Sets the icon bitmap. See {@link PhoneAccount#getIconBitmap}.
+ * Sets the highlight color. See {@link PhoneAccount#getHighlightColor}.
*
- * @param value The icon bitmap.
+ * @param value The highlight color.
* @return The builder.
*/
- public Builder setIconBitmap(Bitmap value) {
- this.mIconBitmap = value;
- return this;
- }
-
- /**
- * Sets the color. See {@link PhoneAccount#getColor}.
- *
- * @param value The resource ID of the icon.
- * @return The builder.
- */
- public Builder setColor(int value) {
- this.mColor = value;
+ public Builder setHighlightColor(int value) {
+ this.mHighlightColor = value;
return this;
}
@@ -318,7 +356,8 @@
mIconResId,
mIconPackageName,
mIconBitmap,
- mColor,
+ mIconTint,
+ mHighlightColor,
mLabel,
mShortDescription,
mSupportedUriSchemes);
@@ -333,7 +372,8 @@
int iconResId,
String iconPackageName,
Bitmap iconBitmap,
- int color,
+ int iconTint,
+ int highlightColor,
CharSequence label,
CharSequence shortDescription,
List<String> supportedUriSchemes) {
@@ -344,7 +384,8 @@
mIconResId = iconResId;
mIconPackageName = iconPackageName;
mIconBitmap = iconBitmap;
- mColor = color;
+ mIconTint = iconTint;
+ mHighlightColor = highlightColor;
mLabel = label;
mShortDescription = shortDescription;
mSupportedUriSchemes = Collections.unmodifiableList(supportedUriSchemes);
@@ -474,7 +515,7 @@
* this method of indicating the icon rather than using {@link #getIconBitmap()}, since it
* leads to less resource usage.
* <p>
- * Clients wishing to display a {@code PhoneAccount} should use {@link #getIcon(Context)}.
+ * Clients wishing to display a {@code PhoneAccount} should use {@link #createIconDrawable(Context)}.
*
* @return A resource ID.
*/
@@ -488,7 +529,7 @@
* If this property is {@code null}, the resource {@link #getIconResId()} will be loaded from
* the package in the {@link ComponentName} of the {@link #getAccountHandle()}.
* <p>
- * Clients wishing to display a {@code PhoneAccount} should use {@link #getIcon(Context)}.
+ * Clients wishing to display a {@code PhoneAccount} should use {@link #createIconDrawable(Context)}.
*
* @return A package name.
*/
@@ -497,12 +538,12 @@
}
/**
- * A highlight color to use in displaying information about this {@code PhoneAccount}.
+ * A tint to apply to the icon of this {@code PhoneAccount}.
*
* @return A hexadecimal color value.
*/
- public int getColor() {
- return mColor;
+ public int getIconTint() {
+ return mIconTint;
}
/**
@@ -511,7 +552,8 @@
* If this property is specified, it is to be considered the preferred icon. Otherwise, the
* resource specified by {@link #getIconResId()} should be used.
* <p>
- * Clients wishing to display a {@code PhoneAccount} should use {@link #getIcon(Context)}.
+ * Clients wishing to display a {@code PhoneAccount} should use
+ * {@link #createIconDrawable(Context)}.
*
* @return A bitmap.
*/
@@ -520,6 +562,15 @@
}
/**
+ * A highlight color to use in displaying information about this {@code PhoneAccount}.
+ *
+ * @return A hexadecimal color value.
+ */
+ public int getHighlightColor() {
+ return mHighlightColor;
+ }
+
+ /**
* Builds and returns an icon {@code Drawable} to represent this {@code PhoneAccount} in a user
* interface. Uses the properties {@link #getIconResId()}, {@link #getIconPackageName()}, and
* {@link #getIconBitmap()} as necessary.
@@ -528,25 +579,26 @@
*
* @return An icon for this {@code PhoneAccount}.
*/
- public Drawable getIcon(Context context) {
+ public Drawable createIconDrawable(Context context) {
if (mIconBitmap != null) {
return new BitmapDrawable(context.getResources(), mIconBitmap);
}
if (mIconResId != 0) {
- String packageName = mIconPackageName == null
- ? mAccountHandle.getComponentName().getPackageName()
- : mIconPackageName;
-
try {
- Context packageContext = context.createPackageContext(packageName, 0);
+ Context packageContext = context.createPackageContext(mIconPackageName, 0);
try {
- return packageContext.getDrawable(mIconResId);
+ Drawable iconDrawable = packageContext.getDrawable(mIconResId);
+ if (mIconTint != NO_COLOR) {
+ iconDrawable.setTint(mIconTint);
+ }
+ return iconDrawable;
} catch (NotFoundException | MissingResourceException e) {
- Log.e(this, e, "Cannot find icon %d in package %s", mIconResId, packageName);
+ Log.e(this, e, "Cannot find icon %d in package %s",
+ mIconResId, mIconPackageName);
}
} catch (PackageManager.NameNotFoundException e) {
- Log.w(this, "Cannot find package %s", packageName);
+ Log.w(this, "Cannot find package %s", mIconPackageName);
}
}
@@ -564,17 +616,37 @@
@Override
public void writeToParcel(Parcel out, int flags) {
- out.writeParcelable(mAccountHandle, 0);
- out.writeParcelable(mAddress, 0);
- out.writeParcelable(mSubscriptionAddress, 0);
+ if (mAccountHandle == null) {
+ out.writeInt(0);
+ } else {
+ out.writeInt(1);
+ mAccountHandle.writeToParcel(out, flags);
+ }
+ if (mAddress == null) {
+ out.writeInt(0);
+ } else {
+ out.writeInt(1);
+ mAddress.writeToParcel(out, flags);
+ }
+ if (mSubscriptionAddress == null) {
+ out.writeInt(0);
+ } else {
+ out.writeInt(1);
+ mSubscriptionAddress.writeToParcel(out, flags);
+ }
out.writeInt(mCapabilities);
out.writeInt(mIconResId);
out.writeString(mIconPackageName);
- out.writeParcelable(mIconBitmap, 0);
- out.writeInt(mColor);
+ if (mIconBitmap == null) {
+ out.writeInt(0);
+ } else {
+ mIconBitmap.writeToParcel(out, flags);
+ }
+ out.writeInt(mIconTint);
+ out.writeInt(mHighlightColor);
out.writeCharSequence(mLabel);
out.writeCharSequence(mShortDescription);
- out.writeList(mSupportedUriSchemes);
+ out.writeStringList(mSupportedUriSchemes);
}
public static final Creator<PhoneAccount> CREATOR
@@ -591,22 +663,34 @@
};
private PhoneAccount(Parcel in) {
- ClassLoader classLoader = PhoneAccount.class.getClassLoader();
-
- mAccountHandle = in.readParcelable(getClass().getClassLoader());
- mAddress = in.readParcelable(getClass().getClassLoader());
- mSubscriptionAddress = in.readParcelable(getClass().getClassLoader());
+ if (in.readInt() > 0) {
+ mAccountHandle = PhoneAccountHandle.CREATOR.createFromParcel(in);
+ } else {
+ mAccountHandle = null;
+ }
+ if (in.readInt() > 0) {
+ mAddress = Uri.CREATOR.createFromParcel(in);
+ } else {
+ mAddress = null;
+ }
+ if (in.readInt() > 0) {
+ mSubscriptionAddress = Uri.CREATOR.createFromParcel(in);
+ } else {
+ mSubscriptionAddress = null;
+ }
mCapabilities = in.readInt();
mIconResId = in.readInt();
mIconPackageName = in.readString();
- mIconBitmap = in.readParcelable(getClass().getClassLoader());
- mColor = in.readInt();
+ if (in.readInt() > 0) {
+ mIconBitmap = Bitmap.CREATOR.createFromParcel(in);
+ } else {
+ mIconBitmap = null;
+ }
+ mIconTint = in.readInt();
+ mHighlightColor = in.readInt();
mLabel = in.readCharSequence();
mShortDescription = in.readCharSequence();
-
- List<String> supportedUriSchemes = new ArrayList<>();
- in.readList(supportedUriSchemes, classLoader);
- mSupportedUriSchemes = Collections.unmodifiableList(supportedUriSchemes);
+ mSupportedUriSchemes = Collections.unmodifiableList(in.createStringArrayList());
}
@Override
diff --git a/telephony/java/android/telephony/CellIdentityCdma.java b/telephony/java/android/telephony/CellIdentityCdma.java
index dbd48d9..b39b4c7 100644
--- a/telephony/java/android/telephony/CellIdentityCdma.java
+++ b/telephony/java/android/telephony/CellIdentityCdma.java
@@ -20,6 +20,8 @@
import android.os.Parcelable;
import android.telephony.Rlog;
+import java.util.Objects;
+
/**
* CellIdentity is to represent a unique CDMA cell
*/
@@ -137,27 +139,25 @@
@Override
public int hashCode() {
- int primeNum = 31;
- return (mNetworkId * primeNum) + (mSystemId * primeNum) + (mBasestationId * primeNum) +
- (mLatitude * primeNum) + (mLongitude * primeNum);
+ return Objects.hash(mNetworkId, mSystemId, mBasestationId, mLatitude, mLongitude);
}
@Override
public boolean equals(Object other) {
- if (super.equals(other)) {
- try {
- CellIdentityCdma o = (CellIdentityCdma)other;
- return mNetworkId == o.mNetworkId &&
- mSystemId == o.mSystemId &&
- mBasestationId == o.mBasestationId &&
- mLatitude == o.mLatitude &&
- mLongitude == o.mLongitude;
- } catch (ClassCastException e) {
- return false;
- }
- } else {
+ if (this == other) {
+ return true;
+ }
+
+ if (!(other instanceof CellIdentityCdma)) {
return false;
}
+
+ CellIdentityCdma o = (CellIdentityCdma) other;
+ return mNetworkId == o.mNetworkId &&
+ mSystemId == o.mSystemId &&
+ mBasestationId == o.mBasestationId &&
+ mLatitude == o.mLatitude &&
+ mLongitude == o.mLongitude;
}
@Override
diff --git a/telephony/java/android/telephony/CellIdentityGsm.java b/telephony/java/android/telephony/CellIdentityGsm.java
index 6f8cc91..90d2aa0 100644
--- a/telephony/java/android/telephony/CellIdentityGsm.java
+++ b/telephony/java/android/telephony/CellIdentityGsm.java
@@ -20,6 +20,8 @@
import android.os.Parcelable;
import android.telephony.Rlog;
+import java.util.Objects;
+
/**
* CellIdentity to represent a unique GSM cell
*/
@@ -113,25 +115,24 @@
@Override
public int hashCode() {
- int primeNum = 31;
- return (mMcc * primeNum) + (mMnc * primeNum) + (mLac * primeNum) + (mCid * primeNum);
+ return Objects.hash(mMcc, mMnc, mLac, mCid);
}
@Override
public boolean equals(Object other) {
- if (super.equals(other)) {
- try {
- CellIdentityGsm o = (CellIdentityGsm)other;
- return mMcc == o.mMcc &&
- mMnc == o.mMnc &&
- mLac == o.mLac &&
- mCid == o.mCid;
- } catch (ClassCastException e) {
- return false;
- }
- } else {
+ if (this == other) {
+ return true;
+ }
+
+ if (!(other instanceof CellIdentityGsm)) {
return false;
}
+
+ CellIdentityGsm o = (CellIdentityGsm) other;
+ return mMcc == o.mMcc &&
+ mMnc == o.mMnc &&
+ mLac == o.mLac &&
+ mCid == o.mCid;
}
@Override
diff --git a/telephony/java/android/telephony/CellIdentityLte.java b/telephony/java/android/telephony/CellIdentityLte.java
index 72578a4..1e7ac08 100644
--- a/telephony/java/android/telephony/CellIdentityLte.java
+++ b/telephony/java/android/telephony/CellIdentityLte.java
@@ -20,6 +20,8 @@
import android.os.Parcelable;
import android.telephony.Rlog;
+import java.util.Objects;
+
/**
* CellIdentity is to represent a unique LTE cell
*/
@@ -117,27 +119,25 @@
@Override
public int hashCode() {
- int primeNum = 31;
- return (mMcc * primeNum) + (mMnc * primeNum) + (mCi * primeNum) + (mPci * primeNum) +
- (mTac * primeNum);
+ return Objects.hash(mMcc, mMnc, mCi, mPci, mTac);
}
@Override
public boolean equals(Object other) {
- if (super.equals(other)) {
- try {
- CellIdentityLte o = (CellIdentityLte)other;
- return mMcc == o.mMcc &&
- mMnc == o.mMnc &&
- mCi == o.mCi &&
- mPci == o.mPci &&
- mTac == o.mTac;
- } catch (ClassCastException e) {
- return false;
- }
- } else {
+ if (this == other) {
+ return true;
+ }
+
+ if (!(other instanceof CellIdentityLte)) {
return false;
}
+
+ CellIdentityLte o = (CellIdentityLte) other;
+ return mMcc == o.mMcc &&
+ mMnc == o.mMnc &&
+ mCi == o.mCi &&
+ mPci == o.mPci &&
+ mTac == o.mTac;
}
@Override
diff --git a/telephony/java/android/telephony/CellIdentityWcdma.java b/telephony/java/android/telephony/CellIdentityWcdma.java
index 2f8fa42..56ee8c9 100644
--- a/telephony/java/android/telephony/CellIdentityWcdma.java
+++ b/telephony/java/android/telephony/CellIdentityWcdma.java
@@ -20,6 +20,8 @@
import android.os.Parcelable;
import android.telephony.Rlog;
+import java.util.Objects;
+
/**
* CellIdentity to represent a unique UMTS cell
*/
@@ -118,27 +120,25 @@
@Override
public int hashCode() {
- int primeNum = 31;
- return (mMcc * primeNum) + (mMnc * primeNum) + (mLac * primeNum) + (mCid * primeNum) +
- (mPsc * primeNum);
+ return Objects.hash(mMcc, mMnc, mLac, mCid, mPsc);
}
@Override
public boolean equals(Object other) {
- if (super.equals(other)) {
- try {
- CellIdentityWcdma o = (CellIdentityWcdma)other;
- return mMcc == o.mMcc &&
- mMnc == o.mMnc &&
- mLac == o.mLac &&
- mCid == o.mCid &&
- mPsc == o.mPsc;
- } catch (ClassCastException e) {
- return false;
- }
- } else {
+ if (this == other) {
+ return true;
+ }
+
+ if (!(other instanceof CellIdentityWcdma)) {
return false;
}
+
+ CellIdentityWcdma o = (CellIdentityWcdma) other;
+ return mMcc == o.mMcc &&
+ mMnc == o.mMnc &&
+ mLac == o.mLac &&
+ mCid == o.mCid &&
+ mPsc == o.mPsc;
}
@Override
diff --git a/telephony/java/android/telephony/SubInfoRecord.aidl b/telephony/java/android/telephony/SubscriptionInfo.aidl
similarity index 95%
rename from telephony/java/android/telephony/SubInfoRecord.aidl
rename to telephony/java/android/telephony/SubscriptionInfo.aidl
index a2de676..1e13732 100755
--- a/telephony/java/android/telephony/SubInfoRecord.aidl
+++ b/telephony/java/android/telephony/SubscriptionInfo.aidl
@@ -16,4 +16,4 @@
package android.telephony;
-parcelable SubInfoRecord;
+parcelable SubscriptionInfo;
diff --git a/telephony/java/android/telephony/SubInfoRecord.java b/telephony/java/android/telephony/SubscriptionInfo.java
similarity index 92%
rename from telephony/java/android/telephony/SubInfoRecord.java
rename to telephony/java/android/telephony/SubscriptionInfo.java
index 89a6bd4..26f17c8 100644
--- a/telephony/java/android/telephony/SubInfoRecord.java
+++ b/telephony/java/android/telephony/SubscriptionInfo.java
@@ -31,7 +31,7 @@
/**
* A Parcelable class for Subscription Information.
*/
-public class SubInfoRecord implements Parcelable {
+public class SubscriptionInfo implements Parcelable {
/**
* Subscription Identifier, this is a device unique number
@@ -99,7 +99,7 @@
/**
* @hide
*/
- public SubInfoRecord(int id, String iccId, int simSlotIndex, CharSequence displayName,
+ public SubscriptionInfo(int id, String iccId, int simSlotIndex, CharSequence displayName,
CharSequence carrierName, int nameSource, int iconTint, String number, int roaming,
Bitmap icon, int mcc, int mnc) {
this.mId = id;
@@ -177,12 +177,12 @@
}
/**
- * Creates and returns an icon {@code Bitmap} to represent this {@code SubInfoRecord} in a user
+ * Creates and returns an icon {@code Bitmap} to represent this {@code SubscriptionInfo} in a user
* interface.
*
* @param context A {@code Context} to get the {@code DisplayMetrics}s from.
*
- * @return A bitmap icon for this {@code SubInfoRecord}.
+ * @return A bitmap icon for this {@code SubscriptionInfo}.
*/
public Bitmap createIconBitmap(Context context) {
int width = mIconBitmap.getWidth();
@@ -259,9 +259,9 @@
return this.mMnc;
}
- public static final Parcelable.Creator<SubInfoRecord> CREATOR = new Parcelable.Creator<SubInfoRecord>() {
+ public static final Parcelable.Creator<SubscriptionInfo> CREATOR = new Parcelable.Creator<SubscriptionInfo>() {
@Override
- public SubInfoRecord createFromParcel(Parcel source) {
+ public SubscriptionInfo createFromParcel(Parcel source) {
int id = source.readInt();
String iccId = source.readString();
int simSlotIndex = source.readInt();
@@ -275,13 +275,13 @@
int mnc = source.readInt();
Bitmap iconBitmap = Bitmap.CREATOR.createFromParcel(source);
- return new SubInfoRecord(id, iccId, simSlotIndex, displayName, carrierName, nameSource,
+ return new SubscriptionInfo(id, iccId, simSlotIndex, displayName, carrierName, nameSource,
iconTint, number, dataRoaming, iconBitmap, mcc, mnc);
}
@Override
- public SubInfoRecord[] newArray(int size) {
- return new SubInfoRecord[size];
+ public SubscriptionInfo[] newArray(int size) {
+ return new SubscriptionInfo[size];
}
};
diff --git a/telephony/java/android/telephony/SubscriptionListener.java b/telephony/java/android/telephony/SubscriptionListener.java
new file mode 100644
index 0000000..5c65333
--- /dev/null
+++ b/telephony/java/android/telephony/SubscriptionListener.java
@@ -0,0 +1,125 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.telephony;
+
+import com.android.internal.telephony.ISub;
+import com.android.internal.telephony.ISubscriptionListener;
+
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.Looper;
+import android.os.Message;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.telephony.Rlog;
+
+import java.util.List;
+
+/**
+ * A listener class for monitoring changes to Subscription state
+ * changes on the device.
+ * <p>
+ * Override the onXxxx methods in this class and passing to the listen method
+ * bitwise-or of the corresponding LISTEN_Xxxx bit flags below.
+ * <p>
+ * Note that access to some of the information is permission-protected. Your
+ * application won't receive updates for protected information unless it has
+ * the appropriate permissions declared in its manifest file. Where permissions
+ * apply, they are noted in the appropriate LISTEN_ flags.
+ */
+public class SubscriptionListener {
+ private static final String LOG_TAG = "SubscriptionListener";
+ private static final boolean DBG = false; // STOPSHIP if true
+
+ /**
+ * Permission for LISTEN_SUBSCRIPTION_INFO_LIST_CHANGED
+ *
+ * @hide
+ */
+ public static final String PERMISSION_LISTEN_SUBSCRIPTION_INFO_LIST_CHANGED =
+ android.Manifest.permission.READ_PHONE_STATE;
+
+ /**
+ * Listen for changes to the SubscriptionInoList when listening for this event
+ * it is guaranteed that on #onSubscriptionInfoChanged will be invoked. This initial
+ * invocation should be used to call SubscriptionManager.getActiveSubscriptionInfoList()
+ * to get the initial list.
+ *
+ * Permissions: android.Manifest.permission.READ_PHONE_STATE
+ * @see #onSubscriptionInfoChanged
+ */
+ public static final int LISTEN_SUBSCRIPTION_INFO_LIST_CHANGED = 0x00000001;
+
+ private final Handler mHandler;
+
+ /**
+ * Create a SubscriptionLitener for the device.
+ *
+ * This class requires Looper.myLooper() not return null. To supply your
+ * own non-null looper use PhoneStateListener(Looper looper) below.
+ */
+ public SubscriptionListener() {
+ this(Looper.myLooper());
+ }
+
+ /**
+ * Create a PhoneStateListener for the Phone using the specified subscription
+ * and non-null Looper.
+ */
+ public SubscriptionListener(Looper looper) {
+ if (DBG) log("ctor: looper=" + looper);
+
+ ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub"));
+ mHandler = new Handler(looper) {
+ @Override
+ public void handleMessage(Message msg) {
+ if (DBG) {
+ log("what=0x" + Integer.toHexString(msg.what) + " msg=" + msg);
+ }
+ switch (msg.what) {
+ case LISTEN_SUBSCRIPTION_INFO_LIST_CHANGED:
+ SubscriptionListener.this.onSubscriptionInfoChanged();
+ break;
+ }
+ }
+ };
+ }
+
+ /**
+ * Callback invoked when there is any change to any SubscriptionInfo.
+ */
+ public void onSubscriptionInfoChanged() {
+ // default implementation empty
+ }
+
+ /**
+ * The callback methods need to be called on the handler thread where
+ * this object was created. If the binder did that for us it'd be nice.
+ */
+ ISubscriptionListener callback = new ISubscriptionListener.Stub() {
+ @Override
+ public void onSubscriptionInfoChanged() {
+ Message msg = Message.obtain(mHandler, LISTEN_SUBSCRIPTION_INFO_LIST_CHANGED);
+ msg.sendToTarget();
+ }
+ };
+
+ private void log(String s) {
+ Rlog.d(LOG_TAG, s);
+ }
+}
diff --git a/telephony/java/android/telephony/SubscriptionManager.java b/telephony/java/android/telephony/SubscriptionManager.java
index 21d225d..78ab6870 100644
--- a/telephony/java/android/telephony/SubscriptionManager.java
+++ b/telephony/java/android/telephony/SubscriptionManager.java
@@ -18,6 +18,7 @@
import android.annotation.SdkConstant;
import android.annotation.SdkConstant.SdkConstantType;
+import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.provider.BaseColumns;
@@ -26,6 +27,7 @@
import android.os.RemoteException;
import com.android.internal.telephony.ISub;
+import com.android.internal.telephony.ITelephonyRegistry;
import com.android.internal.telephony.PhoneConstants;
import java.util.ArrayList;
@@ -43,28 +45,29 @@
private static final boolean DBG = true;
private static final boolean VDBG = false;
- /** An invalid phone identifier */
- public static final int INVALID_PHONE_ID = -1000;
+ /** An invalid subscription identifier */
+ public static final int INVALID_SUB_ID = -1000;
- /** Indicates the caller wants the default phone id. */
- public static final int DEFAULT_PHONE_ID = Integer.MAX_VALUE;
+ /** An invalid phone identifier */
+ /** @hide */
+ public static final int INVALID_PHONE_ID = -1;
/** An invalid slot identifier */
- public static final int INVALID_SLOT_ID = -1000;
+ /** @hide */
+ public static final int INVALID_SLOT_ID = -1;
+
+ /** Indicates the caller wants the default sub id. */
+ /** @hide */
+ public static final int DEFAULT_SUB_ID = Integer.MAX_VALUE;
+
+ /** Indicates the caller wants the default phone id. */
+ /** @hide */
+ public static final int DEFAULT_PHONE_ID = Integer.MAX_VALUE;
/** Indicates the caller wants the default slot id. */
/** @hide */
public static final int DEFAULT_SLOT_ID = Integer.MAX_VALUE;
- /** Indicates the user should be asked which subscription to use. */
- public static final int ASK_USER_SUB_ID = -1001;
-
- /** An invalid subscription identifier */
- public static final int INVALID_SUB_ID = -1000;
-
- /** Indicates the caller wants the default sub id. */
- public static final int DEFAULT_SUB_ID = Integer.MAX_VALUE;
-
/** Minimum possible subid that represents a subscription */
/** @hide */
public static final int MIN_SUB_ID_VALUE = 0;
@@ -77,31 +80,6 @@
/** @hide */
public static final Uri CONTENT_URI = Uri.parse("content://telephony/siminfo");
- /** @hide */
- public static final int DEFAULT_INT_VALUE = -100;
-
- /** @hide */
- public static final String DEFAULT_STRING_VALUE = "N/A";
-
- /** @hide */
- public static final int EXTRA_VALUE_NEW_SIM = 1;
-
- /** @hide */
- public static final int EXTRA_VALUE_REMOVE_SIM = 2;
- /** @hide */
- public static final int EXTRA_VALUE_REPOSITION_SIM = 3;
- /** @hide */
- public static final int EXTRA_VALUE_NOCHANGE = 4;
-
- /** @hide */
- public static final String INTENT_KEY_DETECT_STATUS = "simDetectStatus";
- /** @hide */
- public static final String INTENT_KEY_SIM_COUNT = "simCount";
- /** @hide */
- public static final String INTENT_KEY_NEW_SIM_SLOT = "newSIMSlot";
- /** @hide */
- public static final String INTENT_KEY_NEW_SIM_STATUS = "newSIMStatus";
-
/**
* The ICC ID of a SIM.
* <P>Type: TEXT (String)</P>
@@ -116,6 +94,7 @@
public static final String SIM_ID = "sim_id";
/** SIM is not inserted */
+ /** @hide */
public static final int SIM_NOT_INSERTED = -1;
/**
@@ -237,12 +216,14 @@
/**
* TelephonyProvider column name for the MCC associated with a SIM.
* <P>Type: INTEGER (int)</P>
+ * @hide
*/
public static final String MCC = "mcc";
/**
* TelephonyProvider column name for the MNC associated with a SIM.
* <P>Type: INTEGER (int)</P>
+ * @hide
*/
public static final String MNC = "mnc";
@@ -261,17 +242,70 @@
}
/**
- * Get the SubInfoRecord associated with the subId
- * @param subId The unique SubInfoRecord index in database
- * @return SubInfoRecord, maybe null
+ * Register for changes to events defined by SubscriptionListener.LISTEN_Xxx. Some of
+ * the events will fire as registration completes, this could be before or after
+ * this method returns.
+ *
+ * @param listener an instance of SubscriptionListner with overridden methods the
+ * overridden method should match the bits defined in events.
+ * @param events is one or more of the SubscriptionListener.LISTEN_Xxx bits
*/
- public static SubInfoRecord getSubInfoForSubscriber(int subId) {
+ public static void register(Context context, SubscriptionListener listener, int events) {
+ String pkgForDebug = context != null ? context.getPackageName() : "<unknown>";
+ if (DBG) {
+ logd("SubscriptionManager listen pkgForDebug=" + pkgForDebug
+ + " events=0x" + Integer.toHexString(events) + " listener=" + listener);
+ }
+ try {
+ // We use the TelephonyRegistry as its runs in the system and thus is always
+ // available where as SubscriptionController could crash and not be available
+ ITelephonyRegistry tr = ITelephonyRegistry.Stub.asInterface(ServiceManager.getService(
+ "telephony.registry"));
+ if (tr != null) {
+ tr.registerSubscriptionListener(pkgForDebug, listener.callback, events);
+ }
+ } catch (RemoteException ex) {
+ // Should not happen
+ }
+ }
+
+ /**
+ * Unregister the listener.
+ *
+ * @param context
+ * @param listener
+ */
+ public static void unregister(Context context, SubscriptionListener listener) {
+ String pkgForDebug = context != null ? context.getPackageName() : "<unknown>";
+ if (DBG) {
+ logd("SubscriptionManager unregister pkgForDebug=" + pkgForDebug
+ + " listener=" + listener);
+ }
+ try {
+ // We use the TelephonyRegistry as its runs in the system and thus is always
+ // available where as SubscriptionController could crash and not be available
+ ITelephonyRegistry tr = ITelephonyRegistry.Stub.asInterface(ServiceManager.getService(
+ "telephony.registry"));
+ if (tr != null) {
+ tr.unregisterSubscriptionListener(pkgForDebug, listener.callback);
+ }
+ } catch (RemoteException ex) {
+ // Should not happen
+ }
+ }
+
+ /**
+ * Get the SubscriptionInfo associated with the subId
+ * @param subId The unique SubscriptionInfo index in database
+ * @return SubscriptionInfo, maybe null
+ */
+ public static SubscriptionInfo getSubscriptionInfoForSubscriber(int subId) {
if (!isValidSubId(subId)) {
- logd("[getSubInfoForSubscriberx]- invalid subId");
+ logd("[getSubscriptionInfoForSubscriber]- invalid subId");
return null;
}
- SubInfoRecord subInfo = null;
+ SubscriptionInfo subInfo = null;
try {
ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub"));
@@ -287,19 +321,19 @@
}
/**
- * Get the SubInfoRecord according to an IccId
+ * Get the SubscriptionInfo according to an IccId
* @param iccId the IccId of SIM card
- * @return SubInfoRecord List, maybe empty but not null
+ * @return SubscriptionInfo List, maybe empty but not null
* @hide
*/
- public static List<SubInfoRecord> getSubInfoUsingIccId(String iccId) {
- if (VDBG) logd("[getSubInfoUsingIccId]+ iccId=" + iccId);
+ public static List<SubscriptionInfo> getSubscriptionInfoUsingIccId(String iccId) {
+ if (VDBG) logd("[getSubscriptionInfoUsingIccId]+ iccId=" + iccId);
if (iccId == null) {
- logd("[getSubInfoUsingIccId]- null iccid");
+ logd("[getSubscriptionInfoUsingIccId]- null iccid");
return null;
}
- List<SubInfoRecord> result = null;
+ List<SubscriptionInfo> result = null;
try {
ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub"));
@@ -312,24 +346,24 @@
if (result == null) {
- result = new ArrayList<SubInfoRecord>();
+ result = new ArrayList<SubscriptionInfo>();
}
return result;
}
/**
- * Get the SubInfoRecord according to slotId
+ * Get the SubscriptionInfo according to slotId
* @param slotId the slot which the SIM is inserted
- * @return SubInfoRecord list, maybe empty but not null
+ * @return SubscriptionInfo list, maybe empty but not null
*/
- public static List<SubInfoRecord> getSubInfoUsingSlotId(int slotId) {
+ public static List<SubscriptionInfo> getSubscriptionInfoUsingSlotId(int slotId) {
// FIXME: Consider never returning null
if (!isValidSlotId(slotId)) {
- logd("[getSubInfoUsingSlotId]- invalid slotId");
+ logd("[getSubscriptionInfoUsingSlotId]- invalid slotId");
return null;
}
- List<SubInfoRecord> result = null;
+ List<SubscriptionInfo> result = null;
try {
ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub"));
@@ -342,21 +376,21 @@
if (result == null) {
- result = new ArrayList<SubInfoRecord>();
+ result = new ArrayList<SubscriptionInfo>();
}
return result;
}
/**
- * Get all the SubInfoRecord(s) in subInfo database
- * @return List of all SubInfoRecords in database, include those that were inserted before
+ * Get all the SubscriptionInfo(s) in subInfo database
+ * @return List of all SubscriptionInfos in database, include those that were inserted before
* maybe empty but not null.
* @hide
*/
- public static List<SubInfoRecord> getAllSubInfoList() {
- if (VDBG) logd("[getAllSubInfoList]+");
+ public static List<SubscriptionInfo> getAllSubscriptionInfoList() {
+ if (VDBG) logd("[getAllSubscriptionInfoList]+");
- List<SubInfoRecord> result = null;
+ List<SubscriptionInfo> result = null;
try {
ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub"));
@@ -368,17 +402,17 @@
}
if (result == null) {
- result = new ArrayList<SubInfoRecord>();
+ result = new ArrayList<SubscriptionInfo>();
}
return result;
}
/**
- * Get the SubInfoRecord(s) of the currently inserted SIM(s)
- * @return Array list of currently inserted SubInfoRecord(s) maybe empty but not null
+ * Get the SubscriptionInfo(s) of the currently inserted SIM(s)
+ * @return Array list of currently inserted SubscriptionInfo(s) maybe empty but not null
*/
- public static List<SubInfoRecord> getActiveSubInfoList() {
- List<SubInfoRecord> result = null;
+ public static List<SubscriptionInfo> getActiveSubscriptionInfoList() {
+ List<SubscriptionInfo> result = null;
try {
ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub"));
@@ -390,7 +424,7 @@
}
if (result == null) {
- result = new ArrayList<SubInfoRecord>();
+ result = new ArrayList<SubscriptionInfo>();
}
return result;
}
@@ -400,8 +434,8 @@
* @return all SIM count in database, include what was inserted before
* @hide
*/
- public static int getAllSubInfoCount() {
- if (VDBG) logd("[getAllSubInfoCount]+");
+ public static int getAllSubscriptionInfoCount() {
+ if (VDBG) logd("[getAllSubscriptionInfoCount]+");
int result = 0;
@@ -422,7 +456,7 @@
* @return active SIM count
* @hide
*/
- public static int getActiveSubInfoCount() {
+ public static int getActiveSubscriptionInfoCount() {
int result = 0;
try {
@@ -438,19 +472,19 @@
}
/**
- * Add a new SubInfoRecord to subinfo database if needed
+ * Add a new SubscriptionInfo to subinfo database if needed
* @param iccId the IccId of the SIM card
* @param slotId the slot which the SIM is inserted
* @return the URL of the newly created row or the updated row
* @hide
*/
- public static Uri addSubInfoRecord(String iccId, int slotId) {
- if (VDBG) logd("[addSubInfoRecord]+ iccId:" + iccId + " slotId:" + slotId);
+ public static Uri addSubscriptionInfoRecord(String iccId, int slotId) {
+ if (VDBG) logd("[addSubscriptionInfoRecord]+ iccId:" + iccId + " slotId:" + slotId);
if (iccId == null) {
- logd("[addSubInfoRecord]- null iccId");
+ logd("[addSubscriptionInfoRecord]- null iccId");
}
if (!isValidSlotId(slotId)) {
- logd("[addSubInfoRecord]- invalid slotId");
+ logd("[addSubscriptionInfoRecord]- invalid slotId");
}
try {
@@ -500,7 +534,7 @@
/**
* Set display name by simInfo index
* @param displayName the display name of SIM card
- * @param subId the unique SubInfoRecord index in database
+ * @param subId the unique SubscriptionInfo index in database
* @return the number of records updated
* @hide
*/
@@ -511,7 +545,7 @@
/**
* Set display name by simInfo index with name source
* @param displayName the display name of SIM card
- * @param subId the unique SubInfoRecord index in database
+ * @param subId the unique SubscriptionInfo index in database
* @param nameSource 0: NAME_SOURCE_DEFAULT_SOURCE, 1: NAME_SOURCE_SIM_SOURCE,
* 2: NAME_SOURCE_USER_INPUT, -1 NAME_SOURCE_UNDEFINED
* @return the number of records updated or -1 if invalid subId
@@ -545,7 +579,7 @@
/**
* Set phone number by subId
* @param number the phone number of the SIM
- * @param subId the unique SubInfoRecord index in database
+ * @param subId the unique SubscriptionInfo index in database
* @return the number of records updated
* @hide
*/
@@ -573,7 +607,7 @@
/**
* Set data roaming by simInfo index
* @param roaming 0:Don't allow data when roaming, 1:Allow data when roaming
- * @param subId the unique SubInfoRecord index in database
+ * @param subId the unique SubscriptionInfo index in database
* @return the number of records updated
* @hide
*/
@@ -602,6 +636,7 @@
* Get slotId associated with the subscription.
* @return slotId as a positive integer or a negative value if an error either
* SIM_NOT_INSERTED or INVALID_SLOT_ID.
+ * @hide
*/
public static int getSlotId(int subId) {
if (!isValidSubId(subId)) {
@@ -724,8 +759,8 @@
}
/** @hide */
- public static SubInfoRecord getDefaultVoiceSubInfo() {
- return getSubInfoForSubscriber(getDefaultVoiceSubId());
+ public static SubscriptionInfo getDefaultVoiceSubscriptionInfo() {
+ return getSubscriptionInfoForSubscriber(getDefaultVoiceSubId());
}
/** @hide */
@@ -735,6 +770,7 @@
/**
* @return subId of the DefaultSms subscription or the value INVALID_SUB_ID if an error.
+ * @hide
*/
public static int getDefaultSmsSubId() {
int subId = INVALID_SUB_ID;
@@ -766,8 +802,8 @@
}
/** @hide */
- public static SubInfoRecord getDefaultSmsSubInfo() {
- return getSubInfoForSubscriber(getDefaultSmsSubId());
+ public static SubscriptionInfo getDefaultSmsSubscriptionInfo() {
+ return getSubscriptionInfoForSubscriber(getDefaultSmsSubId());
}
/** @hide */
@@ -806,8 +842,8 @@
}
/** @hide */
- public static SubInfoRecord getDefaultDataSubInfo() {
- return getSubInfoForSubscriber(getDefaultDataSubId());
+ public static SubscriptionInfo getDefaultDataSubscriptionInfo() {
+ return getSubscriptionInfoForSubscriber(getDefaultDataSubId());
}
/** @hide */
@@ -816,7 +852,7 @@
}
/** @hide */
- public static void clearSubInfo() {
+ public static void clearSubscriptionInfo() {
try {
ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub"));
if (iSub != null) {
@@ -863,6 +899,7 @@
/**
* @return true if a valid subId else false
+ * @hide
*/
public static boolean isValidSubId(int subId) {
return subId > INVALID_SUB_ID ;
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index 0246a2d..c7c8b30 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -2106,11 +2106,7 @@
* Returns a constant indicating the call state (cellular) on the device.
*/
public int getCallState() {
- try {
- return getTelecomService().getCallState();
- } catch (RemoteException | NullPointerException e) {
- return CALL_STATE_IDLE;
- }
+ return getCallState(getDefaultSubscription());
}
/**
@@ -3453,75 +3449,6 @@
}
/**
- * Set whether Android should display a simplified Mobile Network Settings UI
- * for the current ICCID.
- * <p>
- * Requires Permission:
- * {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE}
- * Or the calling app has carrier privileges. @see #hasCarrierPrivileges
- *
- * @param enable true means enabling the simplified UI.
- * @hide
- */
- public void enableSimplifiedNetworkSettings(boolean enable) {
- enableSimplifiedNetworkSettingsForSubscriber(getDefaultSubscription(), enable);
- }
-
- /**
- * Set whether Android should display a simplified Mobile Network Settings UI
- * for the current ICCID.
- * <p>
- * Requires Permission:
- * {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE}
- * Or the calling app has carrier privileges. @see #hasCarrierPrivileges
- *
- * @param subId for which the simplified UI should be enabled or disabled.
- * @param enable true means enabling the simplified UI.
- * @hide
- */
- public void enableSimplifiedNetworkSettingsForSubscriber(int subId, boolean enable) {
- try {
- getITelephony().enableSimplifiedNetworkSettingsForSubscriber(subId, enable);
- } catch (RemoteException ex) {
- } catch (NullPointerException ex) {
- }
- }
-
- /**
- * Get whether a simplified Mobile Network Settings UI is enabled for the
- * current ICCID.
- * <p>
- * Requires Permission:
- * {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
- *
- * @return true if the simplified UI is enabled.
- * @hide
- */
- public boolean getSimplifiedNetworkSettingsEnabled() {
- return getSimplifiedNetworkSettingsEnabledForSubscriber(getDefaultSubscription());
- }
-
- /**
- * Get whether a simplified Mobile Network Settings UI is enabled for the
- * current ICCID.
- * <p>
- * Requires Permission:
- * {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
- *
- * @param subId for which the simplified UI should be enabled or disabled.
- * @return true if the simplified UI is enabled.
- * @hide
- */
- public boolean getSimplifiedNetworkSettingsEnabledForSubscriber(int subId) {
- try {
- return getITelephony().getSimplifiedNetworkSettingsEnabledForSubscriber(subId);
- } catch (RemoteException ex) {
- } catch (NullPointerException ex) {
- }
- return false;
- }
-
- /**
* Returns the result and response from RIL for oem request
*
* @param oemReq the data is sent to ril.
diff --git a/telephony/java/com/android/ims/ImsCallProfile.java b/telephony/java/com/android/ims/ImsCallProfile.java
index 8b7901c..9de938a 100644
--- a/telephony/java/com/android/ims/ImsCallProfile.java
+++ b/telephony/java/com/android/ims/ImsCallProfile.java
@@ -114,6 +114,10 @@
public static final String EXTRA_CALL_MODE_CHANGEABLE = "call_mode_changeable";
public static final String EXTRA_CONFERENCE_AVAIL = "conference_avail";
+ // Extra string for internal use only. OEMs should not use
+ // this for packing extras.
+ public static final String EXTRA_OEM_EXTRAS = "OemCallExtras";
+
/**
* Integer extra properties
* oir : Rule for originating identity (number) presentation, MO/MT.
@@ -151,6 +155,18 @@
public static final int DIALSTRING_USSD = 2;
/**
+ * Values for causes that restrict call types
+ */
+ // Default cause not restricted at peer and HD is supported
+ public static final int CALL_RESTRICT_CAUSE_NONE = 0;
+ // Service not supported by RAT at peer
+ public static final int CALL_RESTRICT_CAUSE_RAT = 1;
+ // Service Disabled at peer
+ public static final int CALL_RESTRICT_CAUSE_DISABLED = 2;
+ // HD is not supported
+ public static final int CALL_RESTRICT_CAUSE_HD = 3;
+
+ /**
* String extra properties
* oi : Originating identity (number), MT only
* cna : Calling name
@@ -164,11 +180,10 @@
public int mServiceType;
public int mCallType;
+ public int mRestrictCause = CALL_RESTRICT_CAUSE_NONE;
public Bundle mCallExtras;
public ImsStreamMediaProfile mMediaProfile;
-
-
public ImsCallProfile(Parcel in) {
readFromParcel(in);
}
diff --git a/telephony/java/com/android/ims/ImsStreamMediaProfile.java b/telephony/java/com/android/ims/ImsStreamMediaProfile.java
index 003499c..359b270 100644
--- a/telephony/java/com/android/ims/ImsStreamMediaProfile.java
+++ b/telephony/java/com/android/ims/ImsStreamMediaProfile.java
@@ -41,10 +41,18 @@
* Audio information
*/
public static final int AUDIO_QUALITY_NONE = 0;
- public static final int AUDIO_QUALITY_AMR = (1 << 0);
- public static final int AUDIO_QUALITY_AMR_WB = (1 << 1);
+ public static final int AUDIO_QUALITY_AMR = 1;
+ public static final int AUDIO_QUALITY_AMR_WB = 2;
+ public static final int AUDIO_QUALITY_QCELP13K = 3;
+ public static final int AUDIO_QUALITY_EVRC = 4;
+ public static final int AUDIO_QUALITY_EVRC_B = 5;
+ public static final int AUDIO_QUALITY_EVRC_WB = 6;
+ public static final int AUDIO_QUALITY_EVRC_NW = 7;
+ public static final int AUDIO_QUALITY_GSM_EFR = 8;
+ public static final int AUDIO_QUALITY_GSM_FR = 9;
+ public static final int AUDIO_QUALITY_GSM_HR = 10;
- /**
+ /**
* Video information
*/
public static final int VIDEO_QUALITY_NONE = 0;
diff --git a/telephony/java/com/android/ims/internal/IImsCallSession.aidl b/telephony/java/com/android/ims/internal/IImsCallSession.aidl
index 16b0cd5..d1946e3 100644
--- a/telephony/java/com/android/ims/internal/IImsCallSession.aidl
+++ b/telephony/java/com/android/ims/internal/IImsCallSession.aidl
@@ -55,6 +55,13 @@
ImsCallProfile getLocalCallProfile();
/**
+ * Gets the remote call profile that this session is associated with
+ *
+ * @return the remote call profile that this session is associated with
+ */
+ ImsCallProfile getRemoteCallProfile();
+
+ /**
* Gets the value associated with the specified property of this session.
*
* @return the string value associated with the specified property
diff --git a/telephony/java/com/android/internal/telephony/ISub.aidl b/telephony/java/com/android/internal/telephony/ISub.aidl
index 829620a..d82c492 100755
--- a/telephony/java/com/android/internal/telephony/ISub.aidl
+++ b/telephony/java/com/android/internal/telephony/ISub.aidl
@@ -17,41 +17,42 @@
package com.android.internal.telephony;
import android.app.PendingIntent;
-import android.telephony.SubInfoRecord;
+import android.telephony.SubscriptionInfo;
+import com.android.internal.telephony.ISubscriptionListener;
interface ISub {
/**
- * Get the SubInfoRecord according to an index
- * @param subId The unique SubInfoRecord index in database
- * @return SubInfoRecord, maybe null
+ * Get the SubscriptionInfo according to an index
+ * @param subId The unique SubscriptionInfo index in database
+ * @return SubscriptionInfo, maybe null
*/
- SubInfoRecord getSubInfoForSubscriber(int subId);
+ SubscriptionInfo getSubInfoForSubscriber(int subId);
/**
- * Get the SubInfoRecord according to an IccId
+ * Get the SubscriptionInfo according to an IccId
* @param iccId the IccId of SIM card
- * @return SubInfoRecord, maybe null
+ * @return SubscriptionInfo, maybe null
*/
- List<SubInfoRecord> getSubInfoUsingIccId(String iccId);
+ List<SubscriptionInfo> getSubInfoUsingIccId(String iccId);
/**
- * Get the SubInfoRecord according to slotId
+ * Get the SubscriptionInfo according to slotId
* @param slotId the slot which the SIM is inserted
- * @return SubInfoRecord, maybe null
+ * @return SubscriptionInfo, maybe null
*/
- List<SubInfoRecord> getSubInfoUsingSlotId(int slotId);
+ List<SubscriptionInfo> getSubInfoUsingSlotId(int slotId);
/**
- * Get all the SubInfoRecord(s) in subinfo database
+ * Get all the SubscriptionInfo(s) in subinfo database
* @return Array list of all SubInfoRecords in database, include thsoe that were inserted before
*/
- List<SubInfoRecord> getAllSubInfoList();
+ List<SubscriptionInfo> getAllSubInfoList();
/**
- * Get the SubInfoRecord(s) of the currently inserted SIM(s)
- * @return Array list of currently inserted SubInfoRecord(s)
+ * Get the SubscriptionInfo(s) of the currently inserted SIM(s)
+ * @return Array list of currently inserted SubscriptionInfo(s)
*/
- List<SubInfoRecord> getActiveSubInfoList();
+ List<SubscriptionInfo> getActiveSubInfoList();
/**
* Get the SUB count of all SUB(s) in subinfo database
@@ -66,7 +67,7 @@
int getActiveSubInfoCount();
/**
- * Add a new SubInfoRecord to subinfo database if needed
+ * Add a new SubscriptionInfo to subinfo database if needed
* @param iccId the IccId of the SIM card
* @param slotId the slot which the SIM is inserted
* @return the URL of the newly created row or the updated row
@@ -76,7 +77,7 @@
/**
* Set SIM icon tint color by simInfo index
* @param tint the icon tint color of the SIM
- * @param subId the unique SubInfoRecord index in database
+ * @param subId the unique SubscriptionInfo index in database
* @return the number of records updated
*/
int setIconTint(int tint, int subId);
@@ -84,7 +85,7 @@
/**
* Set display name by simInfo index
* @param displayName the display name of SIM card
- * @param subId the unique SubInfoRecord index in database
+ * @param subId the unique SubscriptionInfo index in database
* @return the number of records updated
*/
int setDisplayName(String displayName, int subId);
@@ -92,7 +93,7 @@
/**
* Set display name by simInfo index with name source
* @param displayName the display name of SIM card
- * @param subId the unique SubInfoRecord index in database
+ * @param subId the unique SubscriptionInfo index in database
* @param nameSource, 0: DEFAULT_SOURCE, 1: SIM_SOURCE, 2: USER_INPUT
* @return the number of records updated
*/
@@ -101,7 +102,7 @@
/**
* Set phone number by subId
* @param number the phone number of the SIM
- * @param subId the unique SubInfoRecord index in database
+ * @param subId the unique SubscriptionInfo index in database
* @return the number of records updated
*/
int setDisplayNumber(String number, int subId);
@@ -109,7 +110,7 @@
/**
* Set data roaming by simInfo index
* @param roaming 0:Don't allow data when roaming, 1:Allow data when roaming
- * @param subId the unique SubInfoRecord index in database
+ * @param subId the unique SubscriptionInfo index in database
* @return the number of records updated
*/
int setDataRoaming(int roaming, int subId);
diff --git a/cmds/app_process/sigchain_proxy.cpp b/telephony/java/com/android/internal/telephony/ISubscriptionListener.aidl
similarity index 78%
copy from cmds/app_process/sigchain_proxy.cpp
copy to telephony/java/com/android/internal/telephony/ISubscriptionListener.aidl
index bb7a678..4ccdea5 100644
--- a/cmds/app_process/sigchain_proxy.cpp
+++ b/telephony/java/com/android/internal/telephony/ISubscriptionListener.aidl
@@ -14,4 +14,11 @@
* limitations under the License.
*/
-#include "sigchainlib/sigchain.cc"
+package com.android.internal.telephony;
+
+import android.telephony.SubscriptionInfo;
+
+oneway interface ISubscriptionListener {
+ void onSubscriptionInfoChanged();
+}
+
diff --git a/telephony/java/com/android/internal/telephony/ITelephony.aidl b/telephony/java/com/android/internal/telephony/ITelephony.aidl
index 13f0e3f..c50261d 100644
--- a/telephony/java/com/android/internal/telephony/ITelephony.aidl
+++ b/telephony/java/com/android/internal/telephony/ITelephony.aidl
@@ -727,24 +727,6 @@
List<String> getCarrierPackageNamesForIntent(in Intent intent);
/**
- * Set whether Android should display a simplified Mobile Network Settings UI
- * for the current ICCID.
- *
- * @param subId for which the simplified UI should be enabled or disabled.
- * @param enable true means enabling the simplified UI.
- */
- void enableSimplifiedNetworkSettingsForSubscriber(int subId, boolean enable);
-
- /**
- * Get whether a simplified Mobile Network Settings UI is enabled for the
- * current ICCID.
- *
- * @param subId for which the simplified UI should be enabled or disabled.
- * @return true if the simplified UI is enabled.
- */
- boolean getSimplifiedNetworkSettingsEnabledForSubscriber(int subId);
-
- /**
* Set the line 1 phone number string and its alphatag for the current ICCID
* for display purpose only, for example, displayed in Phone Status. It won't
* change the actual MSISDN/MDN. To unset alphatag or number, pass in a null
diff --git a/telephony/java/com/android/internal/telephony/ITelephonyRegistry.aidl b/telephony/java/com/android/internal/telephony/ITelephonyRegistry.aidl
index ee3f8b0..1a1f8fe 100644
--- a/telephony/java/com/android/internal/telephony/ITelephonyRegistry.aidl
+++ b/telephony/java/com/android/internal/telephony/ITelephonyRegistry.aidl
@@ -27,8 +27,11 @@
import android.telephony.CellInfo;
import android.telephony.VoLteServiceState;
import com.android.internal.telephony.IPhoneStateListener;
+import com.android.internal.telephony.ISubscriptionListener;
interface ITelephonyRegistry {
+ void registerSubscriptionListener(String pkg, ISubscriptionListener callback, int events);
+ void unregisterSubscriptionListener(String pkg, ISubscriptionListener callback);
void listen(String pkg, IPhoneStateListener callback, int events, boolean notifyNow);
void listenForSubscriber(in int subId, String pkg, IPhoneStateListener callback, int events,
boolean notifyNow);
@@ -63,4 +66,5 @@
void notifyDataConnectionRealTimeInfo(in DataConnectionRealTimeInfo dcRtInfo);
void notifyVoLteServiceStateChanged(in VoLteServiceState lteState);
void notifyOemHookRawEventForSubscriber(in int subId, in byte[] rawData);
+ void notifySubscriptionInfoChanged();
}
diff --git a/telephony/java/com/android/internal/telephony/TelephonyIntents.java b/telephony/java/com/android/internal/telephony/TelephonyIntents.java
index d05e7d1..c67e5d7 100644
--- a/telephony/java/com/android/internal/telephony/TelephonyIntents.java
+++ b/telephony/java/com/android/internal/telephony/TelephonyIntents.java
@@ -312,27 +312,7 @@
public static final String EXTRA_SPN = "spn";
/**
- * <p>Broadcast Action: It indicates one column of a siminfo record has been changed
- * The intent will have the following extra values:</p>
- * <ul>
- * <li><em>columnName</em> - The siminfo column that is updated.</li>
- * <li><em>stringContent</em> - The string value of the updated column.</li>
- * <li><em>intContent</em> - The int value of the updated column.</li>
- * </ul>
- * <p class="note">This is a protected intent that can only be sent
- * by the system.
- */
- public static final String ACTION_SIMINFO_CONTENT_CHANGE
- = "android.intent.action.ACTION_SIMINFO_CONTENT_CHANGE";
-
- /**
* <p>Broadcast Action: It indicates one column of a subinfo record has been changed
- * The intent will have the following extra values:</p>
- * <ul>
- * <li><em>columnName</em> - The siminfo column that is updated.</li>
- * <li><em>stringContent</em> - The string value of the updated column.</li>
- * <li><em>intContent</em> - The int value of the updated column.</li>
- * </ul>
* <p class="note">This is a protected intent that can only be sent
* by the system.
*/
@@ -340,28 +320,14 @@
= "android.intent.action.ACTION_SUBINFO_CONTENT_CHANGE";
/**
- * <p>Broadcast Action: It indicates siminfo update is completed when SIM inserted state change
- * The intent will have the following extra values:</p>
- * <p class="note">This is a protected intent that can only be sent
- * by the system.
- */
- public static final String ACTION_SIMINFO_UPDATED
- = "android.intent.action.ACTION_SIMINFO_UPDATED";
-
- /**
* <p>Broadcast Action: It indicates subinfo record update is completed
* when SIM inserted state change
- * The intent will have the following extra values:</p>
* <p class="note">This is a protected intent that can only be sent
* by the system.
*/
public static final String ACTION_SUBINFO_RECORD_UPDATED
= "android.intent.action.ACTION_SUBINFO_RECORD_UPDATED";
- public static final String EXTRA_COLUMN_NAME = "columnName";
- public static final String EXTRA_INT_CONTENT = "intContent";
- public static final String EXTRA_STRING_CONTENT = "stringContent";
-
/**
* Broadcast Action: The default subscription has changed. This has the following
* extra values:</p>
diff --git a/test-runner/src/android/test/TouchUtils.java b/test-runner/src/android/test/TouchUtils.java
index 67a0bc2..1b854b0 100644
--- a/test-runner/src/android/test/TouchUtils.java
+++ b/test-runner/src/android/test/TouchUtils.java
@@ -564,7 +564,7 @@
final int fromX = xy[0];
final int fromY = xy[1];
- int distance = (int) Math.sqrt(deltaX * deltaX + deltaY * deltaY);
+ int distance = (int) Math.hypot(deltaX, deltaY);
drag(test, fromX, fromX + deltaX, fromY, fromY + deltaY, distance);
@@ -617,7 +617,7 @@
int deltaX = fromX - toX;
int deltaY = fromY - toY;
- int distance = (int)Math.sqrt(deltaX * deltaX + deltaY * deltaY);
+ int distance = (int)Math.hypot(deltaX, deltaY);
drag(test, fromX, toX, fromY, toY, distance);
return distance;
diff --git a/tests/ActivityTests/src/com/google/android/test/activity/ActivityTestMain.java b/tests/ActivityTests/src/com/google/android/test/activity/ActivityTestMain.java
index 94874c8..b065b88c 100644
--- a/tests/ActivityTests/src/com/google/android/test/activity/ActivityTestMain.java
+++ b/tests/ActivityTests/src/com/google/android/test/activity/ActivityTestMain.java
@@ -140,6 +140,8 @@
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
+ Log.i(TAG, "Referrer: " + getReferrer());
+
mAm = (ActivityManager)getSystemService(ACTIVITY_SERVICE);
if (savedInstanceState != null) {
mOverrideConfig = savedInstanceState.getParcelable(KEY_CONFIGURATION);
diff --git a/tests/Camera2Tests/SmartCamera/SimpleCamera/src/androidx/media/filterfw/CropFilter.java b/tests/Camera2Tests/SmartCamera/SimpleCamera/src/androidx/media/filterfw/CropFilter.java
index 91fe21c..6c0f353 100644
--- a/tests/Camera2Tests/SmartCamera/SimpleCamera/src/androidx/media/filterfw/CropFilter.java
+++ b/tests/Camera2Tests/SmartCamera/SimpleCamera/src/androidx/media/filterfw/CropFilter.java
@@ -20,7 +20,6 @@
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Paint;
-import android.util.FloatMath;
import androidx.media.filterfw.Filter;
import androidx.media.filterfw.FrameImage2D;
@@ -90,8 +89,8 @@
// Pull input frame
FrameImage2D inputImage = getConnectedInputPort("image").pullFrame().asFrameImage2D();
int[] inDims = inputImage.getDimensions();
- int[] croppedDims = { (int)FloatMath.ceil(mCropRect.xEdge().length() * inDims[0]),
- (int)FloatMath.ceil(mCropRect.yEdge().length() * inDims[1]) };
+ int[] croppedDims = { (int)Math.ceil(mCropRect.xEdge().length() * inDims[0]),
+ (int)Math.ceil(mCropRect.yEdge().length() * inDims[1]) };
int[] outDims = { getOutputWidth(croppedDims[0], croppedDims[1]),
getOutputHeight(croppedDims[0], croppedDims[1]) };
FrameImage2D outputImage = outPort.fetchAvailableFrame(outDims).asFrameImage2D();
diff --git a/tests/CoreTests/android/core/ProxyTest.java b/tests/CoreTests/android/core/ProxyTest.java
deleted file mode 100644
index 12acfe8..0000000
--- a/tests/CoreTests/android/core/ProxyTest.java
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.core;
-
-import org.apache.http.HttpHost;
-
-import android.content.Context;
-import android.net.Proxy;
-import android.test.AndroidTestCase;
-
-/**
- * Proxy tests
- */
-public class ProxyTest extends AndroidTestCase {
- private Context mContext;
- private HttpHost mHttpHost;
-
- @Override
- protected void setUp() throws Exception {
- super.setUp();
-
- mContext = getContext();
- mHttpHost = null;
- String proxyHost = Proxy.getHost(mContext);
- int proxyPort = Proxy.getPort(mContext);
- if (proxyHost != null) {
- mHttpHost = new HttpHost(proxyHost, proxyPort, "http");
- }
- }
-
- @Override
- protected void tearDown() throws Exception {
- super.tearDown();
- }
-
- /**
- * Bad url parameter should not cause any exception.
- */
- public void testProxyGetPreferredHttpHost_UrlBad() throws Exception {
- assertEquals(mHttpHost, Proxy.getPreferredHttpHost(mContext, null));
- assertEquals(mHttpHost, Proxy.getPreferredHttpHost(mContext, ""));
- assertEquals(mHttpHost, Proxy.getPreferredHttpHost(mContext, "bad:"));
- assertEquals(mHttpHost, Proxy.getPreferredHttpHost(mContext, "bad"));
- assertEquals(mHttpHost, Proxy.getPreferredHttpHost(mContext, "bad:\\"));
- assertEquals(mHttpHost, Proxy.getPreferredHttpHost(mContext, "bad://#"));
- assertEquals(mHttpHost, Proxy.getPreferredHttpHost(mContext, "://#"));
- }
-
- /**
- * Proxy (if available) should be returned when url parameter is not localhost.
- */
- public void testProxyGetPreferredHttpHost_UrlNotlLocalhost() throws Exception {
- assertEquals(mHttpHost, Proxy.getPreferredHttpHost(mContext, "http://"));
- assertEquals(mHttpHost, Proxy.getPreferredHttpHost(mContext, "http://example.com"));
- assertEquals(mHttpHost, Proxy.getPreferredHttpHost(mContext, "http://example.com/"));
- assertEquals(mHttpHost, Proxy.getPreferredHttpHost(mContext, "http://192.168.0.1/"));
- assertEquals(mHttpHost, Proxy.getPreferredHttpHost(mContext, "file:///foo/bar"));
- assertEquals(mHttpHost, Proxy.getPreferredHttpHost(mContext, "rtsp://example.com"));
- assertEquals(mHttpHost, Proxy.getPreferredHttpHost(mContext, "rtsp://example.com/"));
- assertEquals(mHttpHost, Proxy.getPreferredHttpHost(mContext, "javascript:alert(1)"));
- }
-
- /**
- * No proxy should be returned when url parameter is localhost.
- */
- public void testProxyGetPreferredHttpHost_UrlLocalhost() throws Exception {
- assertNull(Proxy.getPreferredHttpHost(mContext, "http://localhost"));
- assertNull(Proxy.getPreferredHttpHost(mContext, "http://localhost/"));
- assertNull(Proxy.getPreferredHttpHost(mContext, "http://localhost/hej.html"));
- assertNull(Proxy.getPreferredHttpHost(mContext, "http://127.0.0.1"));
- assertNull(Proxy.getPreferredHttpHost(mContext, "http://127.0.0.1/"));
- assertNull(Proxy.getPreferredHttpHost(mContext, "http://127.0.0.1/hej.html"));
- assertNull(Proxy.getPreferredHttpHost(mContext, "http://127.0.0.1:80/"));
- assertNull(Proxy.getPreferredHttpHost(mContext, "http://127.0.0.1:8080/"));
- assertNull(Proxy.getPreferredHttpHost(mContext, "rtsp://127.0.0.1/"));
- assertNull(Proxy.getPreferredHttpHost(mContext, "rtsp://localhost/"));
- assertNull(Proxy.getPreferredHttpHost(mContext, "https://localhost/"));
- }
-}
diff --git a/tests/CoreTests/android/core/SSLSocketTest.java b/tests/CoreTests/android/core/SSLSocketTest.java
index b06790b..65062c2 100644
--- a/tests/CoreTests/android/core/SSLSocketTest.java
+++ b/tests/CoreTests/android/core/SSLSocketTest.java
@@ -907,7 +907,7 @@
*/
public void testClientSessionCaching() throws IOException,
KeyManagementException {
- OpenSSLContextImpl context = new OpenSSLContextImpl();
+ OpenSSLContextImpl context = OpenSSLContextImpl.getPreferred();
// Cache size = 2.
FakeClientSessionCache fakeCache = new FakeClientSessionCache();
@@ -1000,7 +1000,7 @@
public void testFileBasedClientSessionCache() throws IOException,
KeyManagementException {
- OpenSSLContextImpl context = new OpenSSLContextImpl();
+ OpenSSLContextImpl context = OpenSSLContextImpl.getPreferred();
String tmpDir = System.getProperty("java.io.tmpdir");
if (tmpDir == null) {
fail("Please set 'java.io.tmpdir' system property.");
diff --git a/tests/OneMedia/Android.mk b/tests/OneMedia/Android.mk
index 4d39728..4feac68 100644
--- a/tests/OneMedia/Android.mk
+++ b/tests/OneMedia/Android.mk
@@ -9,6 +9,9 @@
LOCAL_PACKAGE_NAME := OneMedia
LOCAL_CERTIFICATE := platform
+LOCAL_STATIC_JAVA_LIBRARIES := \
+ android-support-media-protocols
+
LOCAL_PROGUARD_ENABLED := disabled
include $(BUILD_PACKAGE)
diff --git a/tests/OneMedia/AndroidManifest.xml b/tests/OneMedia/AndroidManifest.xml
index beafeb4..95072a4 100644
--- a/tests/OneMedia/AndroidManifest.xml
+++ b/tests/OneMedia/AndroidManifest.xml
@@ -25,6 +25,15 @@
android:name="com.android.onemedia.OnePlayerService"
android:exported="true"
android:process="com.android.onemedia.service" />
+ <service
+ android:name=".provider.OneMediaRouteProvider"
+ android:permission="android.permission.BIND_MEDIA_ROUTE_SERVICE"
+ android:exported="true"
+ android:process="com.android.onemedia.provider">
+ <intent-filter>
+ <action android:name="android.media.routing.MediaRouteService" />
+ </intent-filter>
+ </service>
</application>
</manifest>
diff --git a/tests/OneMedia/src/com/android/onemedia/PlayerSession.java b/tests/OneMedia/src/com/android/onemedia/PlayerSession.java
index 2455c9c..141a209 100644
--- a/tests/OneMedia/src/com/android/onemedia/PlayerSession.java
+++ b/tests/OneMedia/src/com/android/onemedia/PlayerSession.java
@@ -19,17 +19,25 @@
import android.content.Intent;
import android.graphics.Bitmap;
import android.media.MediaMetadata;
+import android.media.routing.MediaRouteSelector;
+import android.media.routing.MediaRouter;
+import android.media.routing.MediaRouter.ConnectionRequest;
+import android.media.routing.MediaRouter.DestinationInfo;
+import android.media.routing.MediaRouter.RouteInfo;
import android.media.session.MediaSession;
import android.media.session.MediaSession.QueueItem;
import android.media.session.MediaSessionManager;
import android.media.session.PlaybackState;
import android.os.Bundle;
+import android.support.media.protocols.MediaPlayerProtocol;
+import android.support.media.protocols.MediaPlayerProtocol.MediaStatus;
import android.os.RemoteException;
import android.os.SystemClock;
import android.util.Log;
import android.view.KeyEvent;
import com.android.onemedia.playback.LocalRenderer;
+import com.android.onemedia.playback.OneMRPRenderer;
import com.android.onemedia.playback.Renderer;
import com.android.onemedia.playback.RequestUtils;
@@ -40,6 +48,7 @@
private static final String TAG = "PlayerSession";
protected MediaSession mSession;
+ protected MediaRouter mRouter;
protected Context mContext;
protected Renderer mRenderer;
protected MediaSession.Callback mCallback;
@@ -75,11 +84,22 @@
.getSystemService(Context.MEDIA_SESSION_SERVICE);
Log.d(TAG, "Creating session for package " + mContext.getBasePackageName());
+ mRouter = new MediaRouter(mContext);
+ mRouter.addSelector(new MediaRouteSelector.Builder()
+ .addRequiredProtocol(MediaPlayerProtocol.class)
+ .build());
+ mRouter.addSelector(new MediaRouteSelector.Builder()
+ .setRequiredFeatures(MediaRouter.ROUTE_FEATURE_LIVE_AUDIO)
+ .setOptionalFeatures(MediaRouter.ROUTE_FEATURE_LIVE_VIDEO)
+ .build());
+ mRouter.setRoutingCallback(new RoutingCallback(), null);
+
mSession = new MediaSession(mContext, "OneMedia");
mSession.setCallback(mCallback);
mSession.setPlaybackState(mPlaybackState);
mSession.setFlags(MediaSession.FLAG_HANDLES_TRANSPORT_CONTROLS
| MediaSession.FLAG_HANDLES_MEDIA_BUTTONS);
+ mSession.setMediaRouter(mRouter);
mSession.setActive(true);
updateMetadata();
}
@@ -97,6 +117,10 @@
mSession.release();
mSession = null;
}
+ if (mRouter != null) {
+ mRouter.release();
+ mRouter = null;
+ }
}
public void setListener(Listener listener) {
@@ -254,4 +278,63 @@
mRenderer.onPause();
}
}
+
+ private class RoutingCallback extends MediaRouter.RoutingCallback {
+ @Override
+ public void onConnectionStateChanged(int state) {
+ if (state == MediaRouter.CONNECTION_STATE_CONNECTING) {
+ if (mRenderer != null) {
+ mRenderer.onStop();
+ }
+ mRenderer = null;
+ updateState(PlaybackState.STATE_CONNECTING);
+ return;
+ }
+
+ MediaRouter.ConnectionInfo connection = mRouter.getConnection();
+ if (connection != null) {
+ MediaPlayerProtocol protocol =
+ connection.getProtocolObject(MediaPlayerProtocol.class);
+ if (protocol != null) {
+ Log.d(TAG, "Connected to route using media player protocol");
+
+ protocol.setCallback(new PlayerCallback(), null);
+ mRenderer = new OneMRPRenderer(protocol);
+ updateState(PlaybackState.STATE_NONE);
+ return;
+ }
+ }
+
+ // Use local route
+ mRenderer = new LocalRenderer(mContext, null);
+ mRenderer.registerListener(mRenderListener);
+ updateState(PlaybackState.STATE_NONE);
+ }
+ }
+
+ private class PlayerCallback extends MediaPlayerProtocol.Callback {
+ @Override
+ public void onStatusUpdated(MediaStatus status, Bundle extras) {
+ if (status != null) {
+ Log.d(TAG, "Received status update: " + status.toBundle());
+ switch (status.getPlayerState()) {
+ case MediaStatus.PLAYER_STATE_BUFFERING:
+ updateState(PlaybackState.STATE_BUFFERING);
+ break;
+ case MediaStatus.PLAYER_STATE_IDLE:
+ updateState(PlaybackState.STATE_STOPPED);
+ break;
+ case MediaStatus.PLAYER_STATE_PAUSED:
+ updateState(PlaybackState.STATE_PAUSED);
+ break;
+ case MediaStatus.PLAYER_STATE_PLAYING:
+ updateState(PlaybackState.STATE_PLAYING);
+ break;
+ case MediaStatus.PLAYER_STATE_UNKNOWN:
+ updateState(PlaybackState.STATE_NONE);
+ break;
+ }
+ }
+ }
+ }
}
diff --git a/tests/OneMedia/src/com/android/onemedia/playback/OneMRPRenderer.java b/tests/OneMedia/src/com/android/onemedia/playback/OneMRPRenderer.java
new file mode 100644
index 0000000..55eb92c
--- /dev/null
+++ b/tests/OneMedia/src/com/android/onemedia/playback/OneMRPRenderer.java
@@ -0,0 +1,47 @@
+package com.android.onemedia.playback;
+
+import android.os.Bundle;
+import android.support.media.protocols.MediaPlayerProtocol;
+import android.support.media.protocols.MediaPlayerProtocol.MediaInfo;
+
+/**
+ * Renderer for communicating with the OneMRP route
+ */
+public class OneMRPRenderer extends Renderer {
+ private final MediaPlayerProtocol mProtocol;
+
+ public OneMRPRenderer(MediaPlayerProtocol protocol) {
+ super(null, null);
+ mProtocol = protocol;
+ }
+
+ @Override
+ public void setContent(Bundle request) {
+ MediaInfo mediaInfo = new MediaInfo(request.getString(RequestUtils.EXTRA_KEY_SOURCE),
+ MediaInfo.STREAM_TYPE_BUFFERED, "audio/mp3");
+ mProtocol.load(mediaInfo, true, 0, null);
+ }
+
+ @Override
+ public boolean onStop() {
+ mProtocol.stop(null);
+ return true;
+ }
+
+ @Override
+ public boolean onPlay() {
+ mProtocol.play(null);
+ return true;
+ }
+
+ @Override
+ public boolean onPause() {
+ mProtocol.pause(null);
+ return true;
+ }
+
+ @Override
+ public long getSeekPosition() {
+ return -1;
+ }
+}
diff --git a/tests/OneMedia/src/com/android/onemedia/provider/OneMediaRouteProvider.java b/tests/OneMedia/src/com/android/onemedia/provider/OneMediaRouteProvider.java
new file mode 100644
index 0000000..5845e48
--- /dev/null
+++ b/tests/OneMedia/src/com/android/onemedia/provider/OneMediaRouteProvider.java
@@ -0,0 +1,270 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.onemedia.provider;
+
+import android.media.routing.MediaRouteSelector;
+import android.media.routing.MediaRouteService;
+import android.media.routing.MediaRouter.ConnectionInfo;
+import android.media.routing.MediaRouter.ConnectionRequest;
+import android.media.routing.MediaRouter.DestinationInfo;
+import android.media.routing.MediaRouter.DiscoveryRequest;
+import android.media.routing.MediaRouter.RouteInfo;
+import android.media.session.PlaybackState;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Process;
+import android.support.media.protocols.MediaPlayerProtocol;
+import android.support.media.protocols.MediaPlayerProtocol.MediaInfo;
+import android.support.media.protocols.MediaPlayerProtocol.MediaStatus;
+import android.os.Looper;
+import android.os.ResultReceiver;
+import android.os.SystemClock;
+import android.util.Log;
+
+import com.android.onemedia.playback.LocalRenderer;
+import com.android.onemedia.playback.Renderer;
+import com.android.onemedia.playback.RequestUtils;
+
+import java.util.ArrayList;
+
+/**
+ * Test of MediaRouteProvider. Show a dummy provider with a simple interface for
+ * playing music.
+ */
+public class OneMediaRouteProvider extends MediaRouteService {
+ private static final String TAG = "OneMRP";
+ private static final boolean DEBUG = true;
+
+ private static final String TEST_DESTINATION_ID = "testDestination";
+ private static final String TEST_ROUTE_ID = "testRoute";
+
+ private Renderer mRenderer;
+ private RenderListener mRenderListener;
+ private PlaybackState mPlaybackState;
+ private Handler mHandler;
+
+ private OneStub mStub;
+
+ @Override
+ public void onCreate() {
+ mHandler = new Handler();
+ mRenderer = new LocalRenderer(this, null);
+ mRenderListener = new RenderListener();
+ PlaybackState.Builder bob = new PlaybackState.Builder();
+ bob.setActions(PlaybackState.ACTION_PAUSE | PlaybackState.ACTION_PLAY);
+ mPlaybackState = bob.build();
+
+ mRenderer.registerListener(mRenderListener);
+ }
+
+ @Override
+ public ClientSession onCreateClientSession(ClientInfo client) {
+ if (client.getUid() != Process.myUid()) {
+ // for testing purposes, only allow connections from this application
+ // since this provider is not fully featured
+ return null;
+ }
+ return new OneSession(client);
+ }
+
+ private final class OneSession extends ClientSession {
+ private final ClientInfo mClient;
+
+ public OneSession(ClientInfo client) {
+ mClient = client;
+ }
+
+ @Override
+ public boolean onStartDiscovery(DiscoveryRequest req, DiscoveryCallback callback) {
+ for (MediaRouteSelector selector : req.getSelectors()) {
+ if (isMatch(selector)) {
+ DestinationInfo destination = new DestinationInfo.Builder(
+ TEST_DESTINATION_ID, getServiceMetadata(), "OneMedia")
+ .setDescription("Test route from OneMedia app.")
+ .build();
+ ArrayList<RouteInfo> routes = new ArrayList<RouteInfo>();
+ routes.add(new RouteInfo.Builder(
+ TEST_ROUTE_ID, destination, selector).build());
+ callback.onDestinationFound(destination, routes);
+ return true;
+ }
+ }
+ return false;
+ }
+
+ @Override
+ public void onStopDiscovery() {
+ }
+
+ @Override
+ public boolean onConnect(ConnectionRequest req, ConnectionCallback callback) {
+ if (req.getRoute().getId().equals(TEST_ROUTE_ID)) {
+ mStub = new OneStub();
+ ConnectionInfo connection = new ConnectionInfo.Builder(req.getRoute())
+ .setProtocolStub(MediaPlayerProtocol.class, mStub)
+ .build();
+ callback.onConnected(connection);
+ return true;
+ }
+ return false;
+ }
+
+ @Override
+ public void onDisconnect() {
+ mStub = null;
+ }
+
+ private boolean isMatch(MediaRouteSelector selector) {
+ if (!selector.containsProtocol(MediaPlayerProtocol.class)) {
+ return false;
+ }
+ for (String protocol : selector.getRequiredProtocols()) {
+ if (!protocol.equals(MediaPlayerProtocol.class.getName())) {
+ return false;
+ }
+ }
+ return true;
+ }
+ }
+
+ private final class OneStub extends MediaPlayerProtocol.Stub {
+ MediaInfo mMediaInfo;
+
+ public OneStub() {
+ super(mHandler);
+ }
+
+ @Override
+ public void onLoad(MediaInfo mediaInfo, boolean autoplay, long playPosition,
+ Bundle extras) {
+ if (DEBUG) {
+ Log.d(TAG, "Attempting to play " + mediaInfo.getContentId());
+ }
+ // look up the route and send a play command to it
+ mMediaInfo = mediaInfo;
+ Bundle bundle = new Bundle();
+ bundle.putString(RequestUtils.EXTRA_KEY_SOURCE, mediaInfo.getContentId());
+ mRenderer.setContent(bundle);
+ }
+
+ @Override
+ public void onPlay(Bundle extras) {
+ mRenderer.onPlay();
+ }
+
+ @Override
+ public void onPause(Bundle extras) {
+ mRenderer.onPause();
+ }
+ }
+
+ private class RenderListener implements Renderer.Listener {
+
+ @Override
+ public void onError(int type, int extra, Bundle extras, Throwable error) {
+ Log.d(TAG, "Sending onError with type " + type + " and extra " + extra);
+ sendStatusUpdate(PlaybackState.STATE_ERROR);
+ }
+
+ @Override
+ public void onStateChanged(int newState) {
+ long position = -1;
+ if (mRenderer != null) {
+ position = mRenderer.getSeekPosition();
+ }
+ int pbState;
+ float rate = 0;
+ String errorMsg = null;
+ switch (newState) {
+ case Renderer.STATE_ENDED:
+ case Renderer.STATE_STOPPED:
+ pbState = PlaybackState.STATE_STOPPED;
+ break;
+ case Renderer.STATE_INIT:
+ case Renderer.STATE_PREPARING:
+ pbState = PlaybackState.STATE_BUFFERING;
+ break;
+ case Renderer.STATE_ERROR:
+ pbState = PlaybackState.STATE_ERROR;
+ break;
+ case Renderer.STATE_PAUSED:
+ pbState = PlaybackState.STATE_PAUSED;
+ break;
+ case Renderer.STATE_PLAYING:
+ pbState = PlaybackState.STATE_PLAYING;
+ rate = 1;
+ break;
+ default:
+ pbState = PlaybackState.STATE_ERROR;
+ errorMsg = "unknown state";
+ break;
+ }
+ PlaybackState.Builder bob = new PlaybackState.Builder(mPlaybackState);
+ bob.setState(pbState, position, rate, SystemClock.elapsedRealtime());
+ bob.setErrorMessage(errorMsg);
+ mPlaybackState = bob.build();
+
+ sendStatusUpdate(mPlaybackState.getState());
+ }
+
+ @Override
+ public void onBufferingUpdate(int percent) {
+ }
+
+ @Override
+ public void onFocusLost() {
+ Log.d(TAG, "Focus lost, pausing");
+ // Don't update state here, we'll get a separate call to
+ // onStateChanged when it pauses
+ mRenderer.onPause();
+ }
+
+ @Override
+ public void onNextStarted() {
+ }
+
+ private void sendStatusUpdate(int state) {
+ if (mStub != null) {
+ MediaStatus status = new MediaStatus(1, mStub.mMediaInfo);
+ switch (state) {
+ case PlaybackState.STATE_BUFFERING:
+ case PlaybackState.STATE_FAST_FORWARDING:
+ case PlaybackState.STATE_REWINDING:
+ case PlaybackState.STATE_SKIPPING_TO_NEXT:
+ case PlaybackState.STATE_SKIPPING_TO_PREVIOUS:
+ status.setPlayerState(MediaStatus.PLAYER_STATE_BUFFERING);
+ break;
+ case PlaybackState.STATE_CONNECTING:
+ case PlaybackState.STATE_STOPPED:
+ status.setPlayerState(MediaStatus.PLAYER_STATE_IDLE);
+ break;
+ case PlaybackState.STATE_PAUSED:
+ status.setPlayerState(MediaStatus.PLAYER_STATE_PAUSED);
+ break;
+ case PlaybackState.STATE_PLAYING:
+ status.setPlayerState(MediaStatus.PLAYER_STATE_PLAYING);
+ break;
+ case PlaybackState.STATE_NONE:
+ case PlaybackState.STATE_ERROR:
+ default:
+ status.setPlayerState(MediaStatus.PLAYER_STATE_UNKNOWN);
+ break;
+ }
+ mStub.sendStatusUpdatedEvent(status, null);
+ }
+ }
+ }
+}
diff --git a/tests/SslLoad/Android.mk b/tests/SslLoad/Android.mk
deleted file mode 100644
index f75be8d..0000000
--- a/tests/SslLoad/Android.mk
+++ /dev/null
@@ -1,10 +0,0 @@
-LOCAL_PATH:= $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_MODULE_TAGS := tests
-
-LOCAL_SRC_FILES := $(call all-subdir-java-files)
-
-LOCAL_PACKAGE_NAME := SslLoad
-
-include $(BUILD_PACKAGE)
diff --git a/tests/SslLoad/AndroidManifest.xml b/tests/SslLoad/AndroidManifest.xml
deleted file mode 100644
index 497b1c7..0000000
--- a/tests/SslLoad/AndroidManifest.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-
-<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.android.sslload">
- <uses-permission android:name="android.permission.INTERNET" />
- <application>
- <activity android:name="SslLoad" android:label="SSL Load">
- <intent-filter>
- <action android:name="android.intent.action.MAIN" />
- <category android:name="android.intent.category.LAUNCHER" />
- </intent-filter>
- </activity>
- </application>
-</manifest>
diff --git a/tests/SslLoad/src/com/android/sslload/SslLoad.java b/tests/SslLoad/src/com/android/sslload/SslLoad.java
deleted file mode 100644
index 62aa524..0000000
--- a/tests/SslLoad/src/com/android/sslload/SslLoad.java
+++ /dev/null
@@ -1,123 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.sslload;
-
-import java.io.IOException;
-import java.net.InetAddress;
-import java.net.UnknownHostException;
-import java.util.Calendar;
-import java.util.Map;
-
-import android.app.Activity;
-import android.content.res.Resources;
-import android.media.MediaPlayer;
-import android.os.Handler;
-import android.os.Vibrator;
-import android.os.Bundle;
-import android.view.Menu;
-import android.view.MenuItem;
-import android.view.View;
-import android.view.View.OnClickListener;
-import android.widget.Button;
-import android.widget.TextView;
-import android.util.Log;
-import android.net.http.AndroidHttpClient;
-import org.apache.http.client.HttpClient;
-import org.apache.http.client.ResponseHandler;
-import org.apache.http.client.methods.HttpGet;
-import org.apache.http.HttpResponse;
-
-public class SslLoad extends Activity implements OnClickListener, Runnable {
-
- private static final String TAG = SslLoad.class.getSimpleName();
-
- private Button button;
- private boolean running = false;
-
- @Override
- public void onCreate(Bundle icicle) {
- super.onCreate(icicle);
-
- Thread requestThread = new Thread(this);
- requestThread.setDaemon(true);
- requestThread.start();
-
- button = new Button(this);
- button.setText("GO");
- button.setOnClickListener(this);
-
- setContentView(button);
- }
-
- @Override
- protected void onStop() {
- super.onStop();
-
- synchronized (this) {
- running = false;
- }
- }
-
- public void onClick(View v) {
- synchronized (this) {
- running = !running;
- button.setText(running ? "STOP" : "GO");
- if (running) {
- this.notifyAll();
- }
- }
- }
-
- public void run() {
- boolean error = false;
- while (true) {
- synchronized (this) {
- while (!running) {
- try {
- this.wait();
- } catch (InterruptedException e) { /* ignored */ }
- }
- }
-
- AndroidHttpClient client = AndroidHttpClient.newInstance(
- "Mozilla/5.001 (windows; U; NT4.0; en-us) Gecko/25250101");
- try {
- // Cert. is for "www.google.com", not "google.com".
- String url = error ? "https://google.com/"
- : "https://www.google.com";
- client.execute(new HttpGet(url),
- new ResponseHandler<Void>() {
- public Void handleResponse(HttpResponse response) {
- /* ignore */
- return null;
- }
- });
- Log.i(TAG, "Request succeeded.");
- } catch (IOException e) {
- Log.w(TAG, "Request failed.", e);
- }
-
- client.close();
-
- try {
- Thread.sleep(1000);
- } catch (InterruptedException e) { /* ignored */ }
-
- error = !error;
- }
- }
-}
diff --git a/tests/VoiceInteraction/src/com/android/test/voiceinteraction/TestInteractionActivity.java b/tests/VoiceInteraction/src/com/android/test/voiceinteraction/TestInteractionActivity.java
index d64eefa..783c78e 100644
--- a/tests/VoiceInteraction/src/com/android/test/voiceinteraction/TestInteractionActivity.java
+++ b/tests/VoiceInteraction/src/com/android/test/voiceinteraction/TestInteractionActivity.java
@@ -18,7 +18,9 @@
import android.app.Activity;
import android.app.VoiceInteractor;
+import android.content.ComponentName;
import android.os.Bundle;
+import android.service.voice.VoiceInteractionService;
import android.util.Log;
import android.view.Gravity;
import android.view.View;
@@ -42,6 +44,13 @@
return;
}
+ if (!VoiceInteractionService.isActiveService(this,
+ new ComponentName(this, MainInteractionService.class))) {
+ Log.w(TAG, "Not current voice interactor!");
+ finish();
+ return;
+ }
+
setContentView(R.layout.test_interaction);
mAbortButton = (Button)findViewById(R.id.abort);
mAbortButton.setOnClickListener(this);
diff --git a/tools/aapt/AaptAssets.cpp b/tools/aapt/AaptAssets.cpp
index b7f64f6..2d35129 100644
--- a/tools/aapt/AaptAssets.cpp
+++ b/tools/aapt/AaptAssets.cpp
@@ -15,7 +15,6 @@
#include <dirent.h>
#include <errno.h>
-static const char* kDefaultLocale = "default";
static const char* kAssetDir = "assets";
static const char* kResourceDir = "res";
static const char* kValuesDir = "values";
@@ -176,7 +175,7 @@
void AaptLocaleValue::setLanguage(const char* languageChars) {
size_t i = 0;
- while ((*languageChars) != '\0') {
+ while ((*languageChars) != '\0' && i < sizeof(language)/sizeof(language[0])) {
language[i++] = tolower(*languageChars);
languageChars++;
}
@@ -184,7 +183,7 @@
void AaptLocaleValue::setRegion(const char* regionChars) {
size_t i = 0;
- while ((*regionChars) != '\0') {
+ while ((*regionChars) != '\0' && i < sizeof(region)/sizeof(region[0])) {
region[i++] = toupper(*regionChars);
regionChars++;
}
@@ -192,7 +191,7 @@
void AaptLocaleValue::setScript(const char* scriptChars) {
size_t i = 0;
- while ((*scriptChars) != '\0') {
+ while ((*scriptChars) != '\0' && i < sizeof(script)/sizeof(script[0])) {
if (i == 0) {
script[i++] = toupper(*scriptChars);
} else {
@@ -204,7 +203,7 @@
void AaptLocaleValue::setVariant(const char* variantChars) {
size_t i = 0;
- while ((*variantChars) != '\0') {
+ while ((*variantChars) != '\0' && i < sizeof(variant)/sizeof(variant[0])) {
variant[i++] = *variantChars;
variantChars++;
}
@@ -1241,7 +1240,7 @@
}
ssize_t
-AaptAssets::slurpResourceZip(Bundle* bundle, const char* filename)
+AaptAssets::slurpResourceZip(Bundle* /* bundle */, const char* filename)
{
int count = 0;
SortedVector<AaptGroupEntry> entries;
diff --git a/tools/aapt/Android.mk b/tools/aapt/Android.mk
index bc9c1f7..b20cb0b 100644
--- a/tools/aapt/Android.mk
+++ b/tools/aapt/Android.mk
@@ -36,7 +36,6 @@
Images.cpp \
Package.cpp \
pseudolocalize.cpp \
- qsort_r_compat.c \
Resource.cpp \
ResourceFilter.cpp \
ResourceIdCache.cpp \
@@ -68,6 +67,7 @@
libziparchive-host
aaptCFlags := -DAAPT_VERSION=\"$(BUILD_NUMBER)\"
+aaptCFLAGS += -Wall -Werror
ifeq ($(HOST_OS),linux)
aaptHostLdLibs += -lrt -ldl -lpthread
@@ -118,6 +118,7 @@
# Build the host tests: libaapt_tests
# ==========================================================
include $(CLEAR_VARS)
+LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
LOCAL_MODULE := libaapt_tests
LOCAL_CFLAGS += $(aaptCFlags)
@@ -139,10 +140,7 @@
LOCAL_MODULE := aapt
LOCAL_CFLAGS += $(aaptCFlags)
LOCAL_SRC_FILES := $(aaptSources) $(aaptMain)
-LOCAL_C_INCLUDES += \
- $(aaptCIncludes) \
- bionic \
- external/stlport/stlport
+LOCAL_C_INCLUDES += $(aaptCIncludes)
LOCAL_SHARED_LIBRARIES := \
libandroidfw \
libutils \
@@ -151,9 +149,9 @@
liblog \
libz
LOCAL_STATIC_LIBRARIES := \
- libstlport_static \
libexpat_static
+include external/stlport/libstlport.mk
include $(BUILD_EXECUTABLE)
endif # Not SDK_ONLY
diff --git a/tools/aapt/Command.cpp b/tools/aapt/Command.cpp
index f5f70c5..b7484a3 100644
--- a/tools/aapt/Command.cpp
+++ b/tools/aapt/Command.cpp
@@ -215,14 +215,15 @@
goto bail;
}
+#ifdef HAVE_ANDROID_OS
+ static const bool kHaveAndroidOs = true;
+#else
+ static const bool kHaveAndroidOs = false;
+#endif
const ResTable& res = assets.getResources(false);
- if (&res == NULL) {
- printf("\nNo resource table found.\n");
- } else {
-#ifndef HAVE_ANDROID_OS
+ if (!kHaveAndroidOs) {
printf("\nResource table:\n");
res.print(false);
-#endif
}
Asset* manifestAsset = assets.openNonAsset("AndroidManifest.xml",
@@ -622,10 +623,7 @@
assets.setConfiguration(config);
const ResTable& res = assets.getResources(false);
- if (&res == NULL) {
- fprintf(stderr, "ERROR: dump failed because no resource table was found\n");
- return 1;
- } else if (res.getError() != NO_ERROR) {
+ if (res.getError() != NO_ERROR) {
fprintf(stderr, "ERROR: dump failed because the resource table is invalid/corrupt.\n");
return 1;
}
diff --git a/tools/aapt/CrunchCache.cpp b/tools/aapt/CrunchCache.cpp
index c4cf6bc..6c39d1d 100644
--- a/tools/aapt/CrunchCache.cpp
+++ b/tools/aapt/CrunchCache.cpp
@@ -101,4 +101,4 @@
time_t sourceDate = mSourceFiles.valueFor(mSourcePath.appendPathCopy(relativePath));
time_t destDate = mDestFiles.valueFor(mDestPath.appendPathCopy(relativePath));
return sourceDate > destDate;
-}
\ No newline at end of file
+}
diff --git a/tools/aapt/Images.cpp b/tools/aapt/Images.cpp
index 5d4a6ac..5ab177b 100644
--- a/tools/aapt/Images.cpp
+++ b/tools/aapt/Images.cpp
@@ -14,7 +14,8 @@
#include <png.h>
#include <zlib.h>
-#define NOISY(x) //x
+// Change this to true for noisy debug output.
+static const bool kIsDebug = false;
static void
png_write_aapt_file(png_structp png_ptr, png_bytep data, png_size_t length)
@@ -28,7 +29,7 @@
static void
-png_flush_aapt_file(png_structp png_ptr)
+png_flush_aapt_file(png_structp /* png_ptr */)
{
}
@@ -156,11 +157,13 @@
png_read_end(read_ptr, read_info);
- NOISY(printf("Image %s: w=%d, h=%d, d=%d, colors=%d, inter=%d, comp=%d\n",
- imageName,
- (int)outImageInfo->width, (int)outImageInfo->height,
- bit_depth, color_type,
- interlace_type, compression_type));
+ if (kIsDebug) {
+ printf("Image %s: w=%d, h=%d, d=%d, colors=%d, inter=%d, comp=%d\n",
+ imageName,
+ (int)outImageInfo->width, (int)outImageInfo->height,
+ bit_depth, color_type,
+ interlace_type, compression_type);
+ }
png_get_IHDR(read_ptr, read_info, &outImageInfo->width,
&outImageInfo->height, &bit_depth, &color_type,
@@ -330,7 +333,7 @@
}
static status_t get_horizontal_layout_bounds_ticks(
- png_bytep row, int width, bool transparent, bool required,
+ png_bytep row, int width, bool transparent, bool /* required */,
int32_t* outLeft, int32_t* outRight, const char** outError)
{
int i;
@@ -368,7 +371,7 @@
}
static status_t get_vertical_layout_bounds_ticks(
- png_bytepp rows, int offset, int height, bool transparent, bool required,
+ png_bytepp rows, int offset, int height, bool transparent, bool /* required */,
int32_t* outTop, int32_t* outBottom, const char** outError)
{
int i;
@@ -493,13 +496,15 @@
*/
image->outlineRadius = 3.4142f * diagonalInset;
- NOISY(printf("outline insets %d %d %d %d, rad %f, alpha %x\n",
- image->outlineInsetsLeft,
- image->outlineInsetsTop,
- image->outlineInsetsRight,
- image->outlineInsetsBottom,
- image->outlineRadius,
- image->outlineAlpha));
+ if (kIsDebug) {
+ printf("outline insets %d %d %d %d, rad %f, alpha %x\n",
+ image->outlineInsetsLeft,
+ image->outlineInsetsTop,
+ image->outlineInsetsRight,
+ image->outlineInsetsBottom,
+ image->outlineRadius,
+ image->outlineAlpha);
+ }
}
@@ -533,41 +538,6 @@
return (color[3]<<24) | (color[0]<<16) | (color[1]<<8) | color[2];
}
-static void select_patch(
- int which, int front, int back, int size, int* start, int* end)
-{
- switch (which) {
- case 0:
- *start = 0;
- *end = front-1;
- break;
- case 1:
- *start = front;
- *end = back-1;
- break;
- case 2:
- *start = back;
- *end = size-1;
- break;
- }
-}
-
-static uint32_t get_color(image_info* image, int hpatch, int vpatch)
-{
- int left, right, top, bottom;
- select_patch(
- hpatch, image->xDivs[0], image->xDivs[1],
- image->width, &left, &right);
- select_patch(
- vpatch, image->yDivs[0], image->yDivs[1],
- image->height, &top, &bottom);
- //printf("Selecting h=%d v=%d: (%d,%d)-(%d,%d)\n",
- // hpatch, vpatch, left, top, right, bottom);
- const uint32_t c = get_color(image->rows, left, top, right, bottom);
- NOISY(printf("Color in (%d,%d)-(%d,%d): #%08x\n", left, top, right, bottom, c));
- return c;
-}
-
static status_t do_9patch(const char* imageName, image_info* image)
{
image->is9Patch = true;
@@ -672,8 +642,10 @@
|| image->layoutBoundsBottom != 0;
if (image->haveLayoutBounds) {
- NOISY(printf("layoutBounds=%d %d %d %d\n", image->layoutBoundsLeft, image->layoutBoundsTop,
- image->layoutBoundsRight, image->layoutBoundsBottom));
+ if (kIsDebug) {
+ printf("layoutBounds=%d %d %d %d\n", image->layoutBoundsLeft, image->layoutBoundsTop,
+ image->layoutBoundsRight, image->layoutBoundsBottom);
+ }
}
// use opacity of pixels to estimate the round rect outline
@@ -695,12 +667,14 @@
image->info9Patch.paddingBottom = H - 2 - image->info9Patch.paddingBottom;
}
- NOISY(printf("Size ticks for %s: x0=%d, x1=%d, y0=%d, y1=%d\n", imageName,
- xDivs[0], xDivs[1],
- yDivs[0], yDivs[1]));
- NOISY(printf("padding ticks for %s: l=%d, r=%d, t=%d, b=%d\n", imageName,
- image->info9Patch.paddingLeft, image->info9Patch.paddingRight,
- image->info9Patch.paddingTop, image->info9Patch.paddingBottom));
+ if (kIsDebug) {
+ printf("Size ticks for %s: x0=%d, x1=%d, y0=%d, y1=%d\n", imageName,
+ xDivs[0], xDivs[1],
+ yDivs[0], yDivs[1]);
+ printf("padding ticks for %s: l=%d, r=%d, t=%d, b=%d\n", imageName,
+ image->info9Patch.paddingLeft, image->info9Patch.paddingRight,
+ image->info9Patch.paddingTop, image->info9Patch.paddingBottom);
+ }
// Remove frame from image.
image->rows = (png_bytepp)malloc((H-2) * sizeof(png_bytep));
@@ -782,7 +756,10 @@
}
c = get_color(image->rows, left, top, right - 1, bottom - 1);
image->colors[colorIndex++] = c;
- NOISY(if (c != Res_png_9patch::NO_COLOR) hasColor = true);
+ if (kIsDebug) {
+ if (c != Res_png_9patch::NO_COLOR)
+ hasColor = true;
+ }
left = right;
}
top = bottom;
@@ -885,7 +862,7 @@
break;
}
if (i == (w - 1)) {
- NOISY(printf("\n"));
+ printf("\n");
}
}
}
@@ -915,8 +892,10 @@
// 2. Every pixel has A == 255 (opaque)
// 3. There are no more than 256 distinct RGBA colors
- // NOISY(printf("Initial image data:\n"));
- // dump_image(w, h, imageInfo.rows, PNG_COLOR_TYPE_RGB_ALPHA);
+ if (kIsDebug) {
+ printf("Initial image data:\n");
+ dump_image(w, h, imageInfo.rows, PNG_COLOR_TYPE_RGB_ALPHA);
+ }
for (j = 0; j < h; j++) {
png_bytep row = imageInfo.rows[j];
@@ -932,15 +911,19 @@
maxGrayDeviation = MAX(ABS(gg - bb), maxGrayDeviation);
maxGrayDeviation = MAX(ABS(bb - rr), maxGrayDeviation);
if (maxGrayDeviation > odev) {
- NOISY(printf("New max dev. = %d at pixel (%d, %d) = (%d %d %d %d)\n",
- maxGrayDeviation, i, j, rr, gg, bb, aa));
+ if (kIsDebug) {
+ printf("New max dev. = %d at pixel (%d, %d) = (%d %d %d %d)\n",
+ maxGrayDeviation, i, j, rr, gg, bb, aa);
+ }
}
// Check if image is really grayscale
if (isGrayscale) {
if (rr != gg || rr != bb) {
- NOISY(printf("Found a non-gray pixel at %d, %d = (%d %d %d %d)\n",
- i, j, rr, gg, bb, aa));
+ if (kIsDebug) {
+ printf("Found a non-gray pixel at %d, %d = (%d %d %d %d)\n",
+ i, j, rr, gg, bb, aa);
+ }
isGrayscale = false;
}
}
@@ -948,8 +931,10 @@
// Check if image is really opaque
if (isOpaque) {
if (aa != 0xff) {
- NOISY(printf("Found a non-opaque pixel at %d, %d = (%d %d %d %d)\n",
- i, j, rr, gg, bb, aa));
+ if (kIsDebug) {
+ printf("Found a non-opaque pixel at %d, %d = (%d %d %d %d)\n",
+ i, j, rr, gg, bb, aa);
+ }
isOpaque = false;
}
}
@@ -971,7 +956,9 @@
*out++ = idx;
if (!match) {
if (num_colors == 256) {
- NOISY(printf("Found 257th color at %d, %d\n", i, j));
+ if (kIsDebug) {
+ printf("Found 257th color at %d, %d\n", i, j);
+ }
isPalette = false;
} else {
colors[num_colors++] = col;
@@ -986,12 +973,14 @@
int bpp = isOpaque ? 3 : 4;
int paletteSize = w * h + bpp * num_colors;
- NOISY(printf("isGrayscale = %s\n", isGrayscale ? "true" : "false"));
- NOISY(printf("isOpaque = %s\n", isOpaque ? "true" : "false"));
- NOISY(printf("isPalette = %s\n", isPalette ? "true" : "false"));
- NOISY(printf("Size w/ palette = %d, gray+alpha = %d, rgb(a) = %d\n",
- paletteSize, 2 * w * h, bpp * w * h));
- NOISY(printf("Max gray deviation = %d, tolerance = %d\n", maxGrayDeviation, grayscaleTolerance));
+ if (kIsDebug) {
+ printf("isGrayscale = %s\n", isGrayscale ? "true" : "false");
+ printf("isOpaque = %s\n", isOpaque ? "true" : "false");
+ printf("isPalette = %s\n", isPalette ? "true" : "false");
+ printf("Size w/ palette = %d, gray+alpha = %d, rgb(a) = %d\n",
+ paletteSize, 2 * w * h, bpp * w * h);
+ printf("Max gray deviation = %d, tolerance = %d\n", maxGrayDeviation, grayscaleTolerance);
+ }
// Choose the best color type for the image.
// 1. Opaque gray - use COLOR_TYPE_GRAY at 1 byte/pixel
@@ -1068,7 +1057,6 @@
png_structp write_ptr, png_infop write_info,
image_info& imageInfo, int grayscaleTolerance)
{
- bool optimize = true;
png_uint_32 width, height;
int color_type;
int bit_depth, interlace_type, compression_type;
@@ -1094,8 +1082,10 @@
png_set_compression_level(write_ptr, Z_BEST_COMPRESSION);
- NOISY(printf("Writing image %s: w = %d, h = %d\n", imageName,
- (int) imageInfo.width, (int) imageInfo.height));
+ if (kIsDebug) {
+ printf("Writing image %s: w = %d, h = %d\n", imageName,
+ (int) imageInfo.width, (int) imageInfo.height);
+ }
png_color rgbPalette[256];
png_byte alphaPalette[256];
@@ -1112,24 +1102,26 @@
color_type = PNG_COLOR_TYPE_RGB_ALPHA;
}
- switch (color_type) {
- case PNG_COLOR_TYPE_PALETTE:
- NOISY(printf("Image %s has %d colors%s, using PNG_COLOR_TYPE_PALETTE\n",
- imageName, paletteEntries,
- hasTransparency ? " (with alpha)" : ""));
- break;
- case PNG_COLOR_TYPE_GRAY:
- NOISY(printf("Image %s is opaque gray, using PNG_COLOR_TYPE_GRAY\n", imageName));
- break;
- case PNG_COLOR_TYPE_GRAY_ALPHA:
- NOISY(printf("Image %s is gray + alpha, using PNG_COLOR_TYPE_GRAY_ALPHA\n", imageName));
- break;
- case PNG_COLOR_TYPE_RGB:
- NOISY(printf("Image %s is opaque RGB, using PNG_COLOR_TYPE_RGB\n", imageName));
- break;
- case PNG_COLOR_TYPE_RGB_ALPHA:
- NOISY(printf("Image %s is RGB + alpha, using PNG_COLOR_TYPE_RGB_ALPHA\n", imageName));
- break;
+ if (kIsDebug) {
+ switch (color_type) {
+ case PNG_COLOR_TYPE_PALETTE:
+ printf("Image %s has %d colors%s, using PNG_COLOR_TYPE_PALETTE\n",
+ imageName, paletteEntries,
+ hasTransparency ? " (with alpha)" : "");
+ break;
+ case PNG_COLOR_TYPE_GRAY:
+ printf("Image %s is opaque gray, using PNG_COLOR_TYPE_GRAY\n", imageName);
+ break;
+ case PNG_COLOR_TYPE_GRAY_ALPHA:
+ printf("Image %s is gray + alpha, using PNG_COLOR_TYPE_GRAY_ALPHA\n", imageName);
+ break;
+ case PNG_COLOR_TYPE_RGB:
+ printf("Image %s is opaque RGB, using PNG_COLOR_TYPE_RGB\n", imageName);
+ break;
+ case PNG_COLOR_TYPE_RGB_ALPHA:
+ printf("Image %s is RGB + alpha, using PNG_COLOR_TYPE_RGB_ALPHA\n", imageName);
+ break;
+ }
}
png_set_IHDR(write_ptr, write_info, imageInfo.width, imageInfo.height,
@@ -1158,7 +1150,9 @@
: (png_byte*)"npOl\0npTc";
// base 9 patch data
- NOISY(printf("Adding 9-patch info...\n"));
+ if (kIsDebug) {
+ printf("Adding 9-patch info...\n");
+ }
strcpy((char*)unknowns[p_index].name, "npTc");
unknowns[p_index].data = (png_byte*)imageInfo.serialize9patch();
unknowns[p_index].size = imageInfo.info9Patch.serializedSize();
@@ -1214,8 +1208,10 @@
}
png_write_image(write_ptr, rows);
-// NOISY(printf("Final image data:\n"));
-// dump_image(imageInfo.width, imageInfo.height, rows, color_type);
+ if (kIsDebug) {
+ printf("Final image data:\n");
+ dump_image(imageInfo.width, imageInfo.height, rows, color_type);
+ }
png_write_end(write_ptr, write_info);
@@ -1231,13 +1227,50 @@
&bit_depth, &color_type, &interlace_type,
&compression_type, NULL);
- NOISY(printf("Image written: w=%d, h=%d, d=%d, colors=%d, inter=%d, comp=%d\n",
- (int)width, (int)height, bit_depth, color_type, interlace_type,
- compression_type));
+ if (kIsDebug) {
+ printf("Image written: w=%d, h=%d, d=%d, colors=%d, inter=%d, comp=%d\n",
+ (int)width, (int)height, bit_depth, color_type, interlace_type,
+ compression_type);
+ }
}
-status_t preProcessImage(const Bundle* bundle, const sp<AaptAssets>& assets,
- const sp<AaptFile>& file, String8* outNewLeafName)
+static bool read_png_protected(png_structp read_ptr, String8& printableName, png_infop read_info,
+ const sp<AaptFile>& file, FILE* fp, image_info* imageInfo) {
+ if (setjmp(png_jmpbuf(read_ptr))) {
+ return false;
+ }
+
+ png_init_io(read_ptr, fp);
+
+ read_png(printableName.string(), read_ptr, read_info, imageInfo);
+
+ const size_t nameLen = file->getPath().length();
+ if (nameLen > 6) {
+ const char* name = file->getPath().string();
+ if (name[nameLen-5] == '9' && name[nameLen-6] == '.') {
+ if (do_9patch(printableName.string(), imageInfo) != NO_ERROR) {
+ return false;
+ }
+ }
+ }
+
+ return true;
+}
+
+static bool write_png_protected(png_structp write_ptr, String8& printableName, png_infop write_info,
+ image_info* imageInfo, const Bundle* bundle) {
+ if (setjmp(png_jmpbuf(write_ptr))) {
+ return false;
+ }
+
+ write_png(printableName.string(), write_ptr, write_info, *imageInfo,
+ bundle->getGrayscaleTolerance());
+
+ return true;
+}
+
+status_t preProcessImage(const Bundle* bundle, const sp<AaptAssets>& /* assets */,
+ const sp<AaptFile>& file, String8* /* outNewLeafName */)
{
String8 ext(file->getPath().getPathExtension());
@@ -1267,8 +1300,6 @@
status_t error = UNKNOWN_ERROR;
- const size_t nameLen = file->getPath().length();
-
fp = fopen(file->getSourceFile().string(), "rb");
if (fp == NULL) {
fprintf(stderr, "%s: ERROR: Unable to open PNG file\n", printableName.string());
@@ -1286,23 +1317,10 @@
goto bail;
}
- if (setjmp(png_jmpbuf(read_ptr))) {
+ if (!read_png_protected(read_ptr, printableName, read_info, file, fp, &imageInfo)) {
goto bail;
}
- png_init_io(read_ptr, fp);
-
- read_png(printableName.string(), read_ptr, read_info, &imageInfo);
-
- if (nameLen > 6) {
- const char* name = file->getPath().string();
- if (name[nameLen-5] == '9' && name[nameLen-6] == '.') {
- if (do_9patch(printableName.string(), &imageInfo) != NO_ERROR) {
- goto bail;
- }
- }
- }
-
write_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, 0, (png_error_ptr)NULL,
(png_error_ptr)NULL);
if (!write_ptr)
@@ -1319,14 +1337,10 @@
png_set_write_fn(write_ptr, (void*)file.get(),
png_write_aapt_file, png_flush_aapt_file);
- if (setjmp(png_jmpbuf(write_ptr)))
- {
+ if (!write_png_protected(write_ptr, printableName, write_info, &imageInfo, bundle)) {
goto bail;
}
- write_png(printableName.string(), write_ptr, write_info, imageInfo,
- bundle->getGrayscaleTolerance());
-
error = NO_ERROR;
if (bundle->getVerbose()) {
diff --git a/tools/aapt/Package.cpp b/tools/aapt/Package.cpp
index dc16e35..cb244ec 100644
--- a/tools/aapt/Package.cpp
+++ b/tools/aapt/Package.cpp
@@ -402,7 +402,6 @@
ssize_t processJarFile(ZipFile* jar, ZipFile* out)
{
- status_t err;
size_t N = jar->getNumEntries();
size_t count = 0;
for (size_t i=0; i<N; i++) {
diff --git a/tools/aapt/Resource.cpp b/tools/aapt/Resource.cpp
index 0d8db13..5bb2ce1 100644
--- a/tools/aapt/Resource.cpp
+++ b/tools/aapt/Resource.cpp
@@ -20,15 +20,20 @@
#include <algorithm>
+// STATUST: mingw does seem to redefine UNKNOWN_ERROR from our enum value, so a cast is necessary.
+
#if HAVE_PRINTF_ZD
# define ZD "%zd"
# define ZD_TYPE ssize_t
+# define STATUST(x) x
#else
# define ZD "%ld"
# define ZD_TYPE long
+# define STATUST(x) (status_t)x
#endif
-#define NOISY(x) // x
+// Set to true for noisy debug output.
+static const bool kIsDebug = false;
// Number of threads to use for preprocessing images.
static const size_t MAX_THREADS = 4;
@@ -129,15 +134,17 @@
String8 leaf(group->getLeaf());
mLeafName = String8(leaf);
mParams = file->getGroupEntry().toParams();
- NOISY(printf("Dir %s: mcc=%d mnc=%d lang=%c%c cnt=%c%c orient=%d ui=%d density=%d touch=%d key=%d inp=%d nav=%d\n",
- group->getPath().string(), mParams.mcc, mParams.mnc,
- mParams.language[0] ? mParams.language[0] : '-',
- mParams.language[1] ? mParams.language[1] : '-',
- mParams.country[0] ? mParams.country[0] : '-',
- mParams.country[1] ? mParams.country[1] : '-',
- mParams.orientation, mParams.uiMode,
- mParams.density, mParams.touchscreen, mParams.keyboard,
- mParams.inputFlags, mParams.navigation));
+ if (kIsDebug) {
+ printf("Dir %s: mcc=%d mnc=%d lang=%c%c cnt=%c%c orient=%d ui=%d density=%d touch=%d key=%d inp=%d nav=%d\n",
+ group->getPath().string(), mParams.mcc, mParams.mnc,
+ mParams.language[0] ? mParams.language[0] : '-',
+ mParams.language[1] ? mParams.language[1] : '-',
+ mParams.country[0] ? mParams.country[0] : '-',
+ mParams.country[1] ? mParams.country[1] : '-',
+ mParams.orientation, mParams.uiMode,
+ mParams.density, mParams.touchscreen, mParams.keyboard,
+ mParams.inputFlags, mParams.navigation);
+ }
mPath = "res";
mPath.appendPath(file->getGroupEntry().toDirName(mResType));
mPath.appendPath(leaf);
@@ -148,7 +155,9 @@
return UNKNOWN_ERROR;
}
- NOISY(printf("file name=%s\n", mBaseName.string()));
+ if (kIsDebug) {
+ printf("file name=%s\n", mBaseName.string());
+ }
return NO_ERROR;
}
@@ -321,7 +330,7 @@
assets->addResource(it.getLeafName(), resPath, it.getFile(), type8);
}
- return hasErrors ? UNKNOWN_ERROR : NO_ERROR;
+ return hasErrors ? STATUST(UNKNOWN_ERROR) : NO_ERROR;
}
class PreProcessImageWorkUnit : public WorkQueue::WorkUnit {
@@ -371,7 +380,7 @@
hasErrors = true;
}
}
- return (hasErrors || (res < NO_ERROR)) ? UNKNOWN_ERROR : NO_ERROR;
+ return (hasErrors || (res < NO_ERROR)) ? STATUST(UNKNOWN_ERROR) : NO_ERROR;
}
static void collect_files(const sp<AaptDir>& dir,
@@ -396,27 +405,35 @@
if (index < 0) {
sp<ResourceTypeSet> set = new ResourceTypeSet();
- NOISY(printf("Creating new resource type set for leaf %s with group %s (%p)\n",
- leafName.string(), group->getPath().string(), group.get()));
+ if (kIsDebug) {
+ printf("Creating new resource type set for leaf %s with group %s (%p)\n",
+ leafName.string(), group->getPath().string(), group.get());
+ }
set->add(leafName, group);
resources->add(resType, set);
} else {
sp<ResourceTypeSet> set = resources->valueAt(index);
index = set->indexOfKey(leafName);
if (index < 0) {
- NOISY(printf("Adding to resource type set for leaf %s group %s (%p)\n",
- leafName.string(), group->getPath().string(), group.get()));
+ if (kIsDebug) {
+ printf("Adding to resource type set for leaf %s group %s (%p)\n",
+ leafName.string(), group->getPath().string(), group.get());
+ }
set->add(leafName, group);
} else {
sp<AaptGroup> existingGroup = set->valueAt(index);
- NOISY(printf("Extending to resource type set for leaf %s group %s (%p)\n",
- leafName.string(), group->getPath().string(), group.get()));
+ if (kIsDebug) {
+ printf("Extending to resource type set for leaf %s group %s (%p)\n",
+ leafName.string(), group->getPath().string(), group.get());
+ }
for (size_t j=0; j<files.size(); j++) {
- NOISY(printf("Adding file %s in group %s resType %s\n",
- files.valueAt(j)->getSourceFile().string(),
- files.keyAt(j).toDirName(String8()).string(),
- resType.string()));
- status_t err = existingGroup->addFile(files.valueAt(j));
+ if (kIsDebug) {
+ printf("Adding file %s in group %s resType %s\n",
+ files.valueAt(j)->getSourceFile().string(),
+ files.keyAt(j).toDirName(String8()).string(),
+ resType.string());
+ }
+ existingGroup->addFile(files.valueAt(j));
}
}
}
@@ -431,12 +448,16 @@
for (int i=0; i<N; i++) {
sp<AaptDir> d = dirs.itemAt(i);
- NOISY(printf("Collecting dir #%d %p: %s, leaf %s\n", i, d.get(), d->getPath().string(),
- d->getLeaf().string()));
+ if (kIsDebug) {
+ printf("Collecting dir #%d %p: %s, leaf %s\n", i, d.get(), d->getPath().string(),
+ d->getLeaf().string());
+ }
collect_files(d, resources);
// don't try to include the res dir
- NOISY(printf("Removing dir leaf %s\n", d->getLeaf().string()));
+ if (kIsDebug) {
+ printf("Removing dir leaf %s\n", d->getLeaf().string());
+ }
ass->removeDir(d->getLeaf());
}
}
@@ -531,7 +552,7 @@
String8(parser.getElementName(&len)).string(), attr);
return ATTR_LEADING_SPACES;
}
- if (str[len-1] == ' ') {
+ if (len != 0 && str[len-1] == ' ') {
fprintf(stderr, "%s:%d: Tag <%s> attribute %s can not end with a space.\n",
path.string(), parser.getLineNumber(),
String8(parser.getElementName(&len)).string(), attr);
@@ -694,9 +715,11 @@
XMLNode::attribute_entry* existingEntry = node->editAttribute(ns, attr);
if (existingEntry != NULL) {
if (replaceExisting) {
- NOISY(printf("Info: AndroidManifest.xml already defines %s (in %s);"
- " overwriting existing value from manifest.\n",
- String8(attr).string(), String8(ns).string()));
+ if (kIsDebug) {
+ printf("Info: AndroidManifest.xml already defines %s (in %s);"
+ " overwriting existing value from manifest.\n",
+ String8(attr).string(), String8(ns).string());
+ }
existingEntry->string = String16(value);
return true;
}
@@ -755,7 +778,9 @@
} else {
className += name;
}
- NOISY(printf("Qualifying class '%s' to '%s'", name.string(), className.string()));
+ if (kIsDebug) {
+ printf("Qualifying class '%s' to '%s'", name.string(), className.string());
+ }
attr->string.setTo(String16(className));
}
}
@@ -859,7 +884,10 @@
}
String8 origPackage(attr->string);
attr->string.setTo(String16(manifestPackageNameOverride));
- NOISY(printf("Overriding package '%s' to be '%s'\n", origPackage.string(), manifestPackageNameOverride));
+ if (kIsDebug) {
+ printf("Overriding package '%s' to be '%s'\n", origPackage.string(),
+ manifestPackageNameOverride);
+ }
// Make class names fully qualified
sp<XMLNode> application = root->getChildElement(String16(), String16("application"));
@@ -1116,8 +1144,9 @@
return err;
}
- NOISY(printf("Creating resources for package %s\n",
- assets->getPackage().string()));
+ if (kIsDebug) {
+ printf("Creating resources for package %s\n", assets->getPackage().string());
+ }
ResourceTable::PackageType packageType = ResourceTable::App;
if (bundle->getBuildSharedLibrary()) {
@@ -1134,7 +1163,9 @@
return err;
}
- NOISY(printf("Found %d included resource packages\n", (int)table.size()));
+ if (kIsDebug) {
+ printf("Found %d included resource packages\n", (int)table.size());
+ }
// Standard flags for compiled XML and optional UTF-8 encoding
int xmlFlags = XML_COMPILE_STANDARD_RESOURCE;
@@ -2039,7 +2070,7 @@
static status_t writeResourceLoadedCallbackForLayoutClasses(
FILE* fp, const sp<AaptAssets>& assets,
- const sp<AaptSymbols>& symbols, int indent, bool includePrivate)
+ const sp<AaptSymbols>& symbols, int indent, bool /* includePrivate */)
{
String16 attr16("attr");
String16 package16(assets->getPackage());
@@ -2343,7 +2374,7 @@
indent--;
fprintf(fp, "%s};\n", getIndentSpace(indent));
- return hasErrors ? UNKNOWN_ERROR : NO_ERROR;
+ return hasErrors ? STATUST(UNKNOWN_ERROR) : NO_ERROR;
}
static status_t writeTextLayoutClasses(
@@ -2429,7 +2460,7 @@
package16.string(), package16.size(), &typeSpecFlags);
//printf("%s:%s/%s: 0x%08x\n", String8(package16).string(),
// String8(attr16).string(), String8(name16).string(), typeSpecFlags);
- const bool pub = (typeSpecFlags&ResTable_typeSpec::SPEC_PUBLIC) != 0;
+ //const bool pub = (typeSpecFlags&ResTable_typeSpec::SPEC_PUBLIC) != 0;
fprintf(fp,
"int styleable %s_%s %d\n",
@@ -2439,7 +2470,7 @@
}
}
- return hasErrors ? UNKNOWN_ERROR : NO_ERROR;
+ return hasErrors ? STATUST(UNKNOWN_ERROR) : NO_ERROR;
}
static status_t writeSymbolClass(
@@ -2770,7 +2801,7 @@
void
addProguardKeepMethodRule(ProguardKeepSet* keep, const String8& memberName,
- const char* pkg, const String8& srcName, int line)
+ const char* /* pkg */, const String8& srcName, int line)
{
String8 rule("-keepclassmembers class * { *** ");
rule += memberName;
@@ -3098,7 +3129,7 @@
}
status_t
-writeDependencyPreReqs(Bundle* bundle, const sp<AaptAssets>& assets, FILE* fp, bool includeRaw)
+writeDependencyPreReqs(Bundle* /* bundle */, const sp<AaptAssets>& assets, FILE* fp, bool includeRaw)
{
status_t deps = -1;
deps += writePathsToFile(assets->getFullResPaths(), fp);
diff --git a/tools/aapt/ResourceFilter.cpp b/tools/aapt/ResourceFilter.cpp
index fc95e14..8693999 100644
--- a/tools/aapt/ResourceFilter.cpp
+++ b/tools/aapt/ResourceFilter.cpp
@@ -41,6 +41,13 @@
// Ignore the version
entry.second &= ~ResTable_config::CONFIG_VERSION;
+ // Ignore any densities. Those are best handled in --preferred-density
+ if ((entry.second & ResTable_config::CONFIG_DENSITY) != 0) {
+ fprintf(stderr, "warning: ignoring flag -c %s. Use --preferred-density instead.\n", entry.first.toString().string());
+ entry.first.density = 0;
+ entry.second &= ~ResTable_config::CONFIG_DENSITY;
+ }
+
mConfigMask |= entry.second;
}
diff --git a/tools/aapt/ResourceTable.cpp b/tools/aapt/ResourceTable.cpp
index bdc6586..69f1ec3 100644
--- a/tools/aapt/ResourceTable.cpp
+++ b/tools/aapt/ResourceTable.cpp
@@ -17,7 +17,24 @@
#include <utils/TypeHelpers.h>
#include <stdarg.h>
-#define NOISY(x) //x
+// SSIZE: mingw does not have signed size_t == ssize_t.
+// STATUST: mingw does seem to redefine UNKNOWN_ERROR from our enum value, so a cast is necessary.
+#if HAVE_PRINTF_ZD
+# define SSIZE(x) x
+# define STATUST(x) x
+#else
+# define SSIZE(x) (signed size_t)x
+# define STATUST(x) (status_t)x
+#endif
+
+// Set to true for noisy debug output.
+static const bool kIsDebug = false;
+
+#if PRINT_STRING_METRICS
+static const bool kPrintStringMetrics = true;
+#else
+static const bool kPrintStringMetrics = false;
+#endif
status_t compileXmlFile(const Bundle* bundle,
const sp<AaptAssets>& assets,
@@ -89,9 +106,11 @@
if (table->modifyForCompat(bundle, resourceName, target, root) != NO_ERROR) {
return UNKNOWN_ERROR;
}
-
- NOISY(printf("Input XML Resource:\n"));
- NOISY(root->print());
+
+ if (kIsDebug) {
+ printf("Input XML Resource:\n");
+ root->print();
+ }
err = root->flatten(target,
(options&XML_COMPILE_STRIP_COMMENTS) != 0,
(options&XML_COMPILE_STRIP_RAW_VALUES) != 0);
@@ -99,19 +118,18 @@
return err;
}
- NOISY(printf("Output XML Resource:\n"));
- NOISY(ResXMLTree tree;
+ if (kIsDebug) {
+ printf("Output XML Resource:\n");
+ ResXMLTree tree;
tree.setTo(target->getData(), target->getSize());
- printXMLBlock(&tree));
+ printXMLBlock(&tree);
+ }
target->setCompressionMethod(ZipEntry::kCompressDeflated);
return err;
}
-#undef NOISY
-#define NOISY(x) //x
-
struct flag_entry
{
const char16_t* name;
@@ -580,7 +598,7 @@
const String16& itemIdent,
int32_t curFormat,
bool isFormatted,
- const String16& product,
+ const String16& /* product */,
PseudolocalizationMethod pseudolocalize,
const bool overwrite,
ResourceTable* outTable)
@@ -596,16 +614,18 @@
if (err != NO_ERROR) {
return err;
}
-
- NOISY(printf("Adding resource bag entry l=%c%c c=%c%c orien=%d d=%d "
- " pid=%s, bag=%s, id=%s: %s\n",
- config.language[0], config.language[1],
- config.country[0], config.country[1],
- config.orientation, config.density,
- String8(parentIdent).string(),
- String8(ident).string(),
- String8(itemIdent).string(),
- String8(str).string()));
+
+ if (kIsDebug) {
+ printf("Adding resource bag entry l=%c%c c=%c%c orien=%d d=%d "
+ " pid=%s, bag=%s, id=%s: %s\n",
+ config.language[0], config.language[1],
+ config.country[0], config.country[1],
+ config.orientation, config.density,
+ String8(parentIdent).string(),
+ String8(ident).string(),
+ String8(itemIdent).string(),
+ String8(str).string());
+ }
err = outTable->addBag(SourcePos(in->getPrintableSource(), block->getLineNumber()),
myPackage, curType, ident, parentIdent, itemIdent, str,
@@ -741,11 +761,13 @@
}
}
- NOISY(printf("Adding resource entry l=%c%c c=%c%c orien=%d d=%d id=%s: %s\n",
- config.language[0], config.language[1],
- config.country[0], config.country[1],
- config.orientation, config.density,
- String8(ident).string(), String8(str).string()));
+ if (kIsDebug) {
+ printf("Adding resource entry l=%c%c c=%c%c orien=%d d=%d id=%s: %s\n",
+ config.language[0], config.language[1],
+ config.country[0], config.country[1],
+ config.orientation, config.density,
+ String8(ident).string(), String8(str).string());
+ }
err = outTable->addEntry(SourcePos(in->getPrintableSource(), block->getLineNumber()),
myPackage, curType, ident, str, &spans, &config,
@@ -1714,7 +1736,7 @@
}
}
- return hasErrors ? UNKNOWN_ERROR : NO_ERROR;
+ return hasErrors ? STATUST(UNKNOWN_ERROR) : NO_ERROR;
}
ResourceTable::ResourceTable(Bundle* bundle, const String16& assetsPackage, ResourceTable::PackageType type)
@@ -1853,7 +1875,7 @@
const String16& bagParent,
const ResTable_config* params,
bool overlay,
- bool replace, bool isId)
+ bool replace, bool /* isId */)
{
status_t result = NO_ERROR;
@@ -2152,22 +2174,25 @@
ref.string(), ref.size(), &package, &type, &name,
defType, defPackage ? defPackage:&mAssetsPackage,
outErrorMsg, &refOnlyPublic)) {
- NOISY(printf("Expanding resource: ref=%s\n",
- String8(ref).string()));
- NOISY(printf("Expanding resource: defType=%s\n",
- defType ? String8(*defType).string() : "NULL"));
- NOISY(printf("Expanding resource: defPackage=%s\n",
- defPackage ? String8(*defPackage).string() : "NULL"));
- NOISY(printf("Expanding resource: ref=%s\n", String8(ref).string()));
- NOISY(printf("Expanded resource: p=%s, t=%s, n=%s, res=0\n",
- String8(package).string(), String8(type).string(),
- String8(name).string()));
+ if (kIsDebug) {
+ printf("Expanding resource: ref=%s\n", String8(ref).string());
+ printf("Expanding resource: defType=%s\n",
+ defType ? String8(*defType).string() : "NULL");
+ printf("Expanding resource: defPackage=%s\n",
+ defPackage ? String8(*defPackage).string() : "NULL");
+ printf("Expanding resource: ref=%s\n", String8(ref).string());
+ printf("Expanded resource: p=%s, t=%s, n=%s, res=0\n",
+ String8(package).string(), String8(type).string(),
+ String8(name).string());
+ }
return 0;
}
uint32_t res = getResId(package, type, name, onlyPublic && refOnlyPublic);
- NOISY(printf("Expanded resource: p=%s, t=%s, n=%s, res=%d\n",
- String8(package).string(), String8(type).string(),
- String8(name).string(), res));
+ if (kIsDebug) {
+ printf("Expanded resource: p=%s, t=%s, n=%s, res=%d\n",
+ String8(package).string(), String8(type).string(),
+ String8(name).string(), res);
+ }
if (res == 0) {
if (outErrorMsg)
*outErrorMsg = "No resource found that matches the given name";
@@ -2234,9 +2259,11 @@
} else {
configStr = "(null)";
}
- NOISY(printf("Adding to pool string style #%d config %s: %s\n",
- style != NULL ? style->size() : 0,
- configStr.string(), String8(finalStr).string()));
+ if (kIsDebug) {
+ printf("Adding to pool string style #%zu config %s: %s\n",
+ style != NULL ? style->size() : 0U,
+ configStr.string(), String8(finalStr).string());
+ }
if (style != NULL && style->size() > 0) {
outValue->data = pool->add(finalStr, *style, configTypeName, config);
} else {
@@ -2880,9 +2907,9 @@
const size_t typeStringsStart = data->getSize();
sp<AaptFile> strFile = p->getTypeStringsData();
ssize_t amt = data->writeData(strFile->getData(), strFile->getSize());
- #if PRINT_STRING_METRICS
- fprintf(stderr, "**** type strings: %d\n", amt);
- #endif
+ if (kPrintStringMetrics) {
+ fprintf(stderr, "**** type strings: %zd\n", SSIZE(amt));
+ }
strAmt += amt;
if (amt < 0) {
return amt;
@@ -2890,9 +2917,9 @@
const size_t keyStringsStart = data->getSize();
strFile = p->getKeyStringsData();
amt = data->writeData(strFile->getData(), strFile->getSize());
- #if PRINT_STRING_METRICS
- fprintf(stderr, "**** key strings: %d\n", amt);
- #endif
+ if (kPrintStringMetrics) {
+ fprintf(stderr, "**** key strings: %zd\n", SSIZE(amt));
+ }
strAmt += amt;
if (amt < 0) {
return amt;
@@ -2984,35 +3011,37 @@
// We need to write one type chunk for each configuration for
// which we have entries in this type.
- const size_t NC = t->getUniqueConfigs().size();
+ const size_t NC = t != NULL ? t->getUniqueConfigs().size() : 0;
const size_t typeSize = sizeof(ResTable_type) + sizeof(uint32_t)*N;
for (size_t ci=0; ci<NC; ci++) {
ConfigDescription config = t->getUniqueConfigs().itemAt(ci);
- NOISY(printf("Writing config %d config: imsi:%d/%d lang:%c%c cnt:%c%c "
- "orien:%d ui:%d touch:%d density:%d key:%d inp:%d nav:%d sz:%dx%d "
- "sw%ddp w%ddp h%ddp dir:%d\n",
- ti+1,
- config.mcc, config.mnc,
- config.language[0] ? config.language[0] : '-',
- config.language[1] ? config.language[1] : '-',
- config.country[0] ? config.country[0] : '-',
- config.country[1] ? config.country[1] : '-',
- config.orientation,
- config.uiMode,
- config.touchscreen,
- config.density,
- config.keyboard,
- config.inputFlags,
- config.navigation,
- config.screenWidth,
- config.screenHeight,
- config.smallestScreenWidthDp,
- config.screenWidthDp,
- config.screenHeightDp,
- config.layoutDirection));
+ if (kIsDebug) {
+ printf("Writing config %zu config: imsi:%d/%d lang:%c%c cnt:%c%c "
+ "orien:%d ui:%d touch:%d density:%d key:%d inp:%d nav:%d sz:%dx%d "
+ "sw%ddp w%ddp h%ddp layout:%d\n",
+ ti + 1,
+ config.mcc, config.mnc,
+ config.language[0] ? config.language[0] : '-',
+ config.language[1] ? config.language[1] : '-',
+ config.country[0] ? config.country[0] : '-',
+ config.country[1] ? config.country[1] : '-',
+ config.orientation,
+ config.uiMode,
+ config.touchscreen,
+ config.density,
+ config.keyboard,
+ config.inputFlags,
+ config.navigation,
+ config.screenWidth,
+ config.screenHeight,
+ config.smallestScreenWidthDp,
+ config.screenWidthDp,
+ config.screenHeightDp,
+ config.screenLayout);
+ }
if (filterable && !filter->match(config)) {
continue;
@@ -3034,28 +3063,30 @@
tHeader->entryCount = htodl(N);
tHeader->entriesStart = htodl(typeSize);
tHeader->config = config;
- NOISY(printf("Writing type %d config: imsi:%d/%d lang:%c%c cnt:%c%c "
- "orien:%d ui:%d touch:%d density:%d key:%d inp:%d nav:%d sz:%dx%d "
- "sw%ddp w%ddp h%ddp dir:%d\n",
- ti+1,
- tHeader->config.mcc, tHeader->config.mnc,
- tHeader->config.language[0] ? tHeader->config.language[0] : '-',
- tHeader->config.language[1] ? tHeader->config.language[1] : '-',
- tHeader->config.country[0] ? tHeader->config.country[0] : '-',
- tHeader->config.country[1] ? tHeader->config.country[1] : '-',
- tHeader->config.orientation,
- tHeader->config.uiMode,
- tHeader->config.touchscreen,
- tHeader->config.density,
- tHeader->config.keyboard,
- tHeader->config.inputFlags,
- tHeader->config.navigation,
- tHeader->config.screenWidth,
- tHeader->config.screenHeight,
- tHeader->config.smallestScreenWidthDp,
- tHeader->config.screenWidthDp,
- tHeader->config.screenHeightDp,
- tHeader->config.layoutDirection));
+ if (kIsDebug) {
+ printf("Writing type %zu config: imsi:%d/%d lang:%c%c cnt:%c%c "
+ "orien:%d ui:%d touch:%d density:%d key:%d inp:%d nav:%d sz:%dx%d "
+ "sw%ddp w%ddp h%ddp layout:%d\n",
+ ti + 1,
+ tHeader->config.mcc, tHeader->config.mnc,
+ tHeader->config.language[0] ? tHeader->config.language[0] : '-',
+ tHeader->config.language[1] ? tHeader->config.language[1] : '-',
+ tHeader->config.country[0] ? tHeader->config.country[0] : '-',
+ tHeader->config.country[1] ? tHeader->config.country[1] : '-',
+ tHeader->config.orientation,
+ tHeader->config.uiMode,
+ tHeader->config.touchscreen,
+ tHeader->config.density,
+ tHeader->config.keyboard,
+ tHeader->config.inputFlags,
+ tHeader->config.navigation,
+ tHeader->config.screenWidth,
+ tHeader->config.screenHeight,
+ tHeader->config.smallestScreenWidthDp,
+ tHeader->config.screenWidthDp,
+ tHeader->config.screenHeightDp,
+ tHeader->config.screenLayout);
+ }
tHeader->config.swapHtoD();
// Build the entries inside of this type.
@@ -3145,10 +3176,10 @@
ssize_t amt = (dest->getSize()-strStart);
strAmt += amt;
- #if PRINT_STRING_METRICS
- fprintf(stderr, "**** value strings: %d\n", amt);
- fprintf(stderr, "**** total strings: %d\n", strAmt);
- #endif
+ if (kPrintStringMetrics) {
+ fprintf(stderr, "**** value strings: %zd\n", SSIZE(amt));
+ fprintf(stderr, "**** total strings: %zd\n", SSIZE(strAmt));
+ }
for (pi=0; pi<flatPackages.size(); pi++) {
err = dest->writeData(flatPackages[pi]->getData(),
@@ -3163,13 +3194,10 @@
(((uint8_t*)dest->getData()) + dataStart);
header->header.size = htodl(dest->getSize() - dataStart);
- NOISY(aout << "Resource table:"
- << HexDump(dest->getData(), dest->getSize()) << endl);
-
- #if PRINT_STRING_METRICS
- fprintf(stderr, "**** total resource table size: %d / %d%% strings\n",
- dest->getSize(), (strAmt*100)/dest->getSize());
- #endif
+ if (kPrintStringMetrics) {
+ fprintf(stderr, "**** total resource table size: %zu / %zu%% strings\n",
+ dest->getSize(), (size_t)(strAmt*100)/dest->getSize());
+ }
return NO_ERROR;
}
@@ -3177,7 +3205,9 @@
status_t ResourceTable::flattenLibraryTable(const sp<AaptFile>& dest, const Vector<sp<Package> >& libs) {
// Write out the library table if necessary
if (libs.size() > 0) {
- NOISY(fprintf(stderr, "Writing library reference table\n"));
+ if (kIsDebug) {
+ fprintf(stderr, "Writing library reference table\n");
+ }
const size_t libStart = dest->getSize();
const size_t count = libs.size();
@@ -3194,9 +3224,11 @@
for (size_t i = 0; i < count; i++) {
const size_t entryStart = dest->getSize();
sp<Package> libPackage = libs[i];
- NOISY(fprintf(stderr, " Entry %s -> 0x%02x\n",
+ if (kIsDebug) {
+ fprintf(stderr, " Entry %s -> 0x%02x\n",
String8(libPackage->getName()).string(),
- (uint8_t)libPackage->getAssignedId()));
+ (uint8_t)libPackage->getAssignedId());
+ }
ResTable_lib_entry* entry = (ResTable_lib_entry*) dest->editDataInRange(
entryStart, sizeof(ResTable_lib_entry));
@@ -3444,9 +3476,11 @@
if (it.isId) {
if (!table->hasBagOrEntry(key, &id16, &package)) {
String16 value("false");
- NOISY(fprintf(stderr, "Generating %s:id/%s\n",
- String8(package).string(),
- String8(key).string()));
+ if (kIsDebug) {
+ fprintf(stderr, "Generating %s:id/%s\n",
+ String8(package).string(),
+ String8(key).string());
+ }
status_t err = table->addEntry(SourcePos(String8("<generated>"), 0), package,
id16, key, value);
if (err != NO_ERROR) {
@@ -3479,7 +3513,7 @@
}
status_t ResourceTable::Entry::assignResourceIds(ResourceTable* table,
- const String16& package)
+ const String16& /* package */)
{
bool hasErrors = false;
@@ -3512,7 +3546,7 @@
}
}
}
- return hasErrors ? UNKNOWN_ERROR : NO_ERROR;
+ return hasErrors ? STATUST(UNKNOWN_ERROR) : NO_ERROR;
}
status_t ResourceTable::Entry::prepareFlatten(StringPool* strings, ResourceTable* table,
@@ -3571,22 +3605,20 @@
return NO_ERROR;
}
-ssize_t ResourceTable::Entry::flatten(Bundle* bundle, const sp<AaptFile>& data, bool isPublic)
+ssize_t ResourceTable::Entry::flatten(Bundle* /* bundle */, const sp<AaptFile>& data, bool isPublic)
{
size_t amt = 0;
ResTable_entry header;
memset(&header, 0, sizeof(header));
header.size = htods(sizeof(header));
- const type ty = this != NULL ? mType : TYPE_ITEM;
- if (this != NULL) {
- if (ty == TYPE_BAG) {
- header.flags |= htods(header.FLAG_COMPLEX);
- }
- if (isPublic) {
- header.flags |= htods(header.FLAG_PUBLIC);
- }
- header.key.index = htodl(mNameIndex);
+ const type ty = mType;
+ if (ty == TYPE_BAG) {
+ header.flags |= htods(header.FLAG_COMPLEX);
}
+ if (isPublic) {
+ header.flags |= htods(header.FLAG_PUBLIC);
+ }
+ header.key.index = htodl(mNameIndex);
if (ty != TYPE_BAG) {
status_t err = data->writeData(&header, sizeof(header));
if (err != NO_ERROR) {
@@ -3761,10 +3793,11 @@
sp<Entry> e = c->getEntries().valueFor(cdesc);
if (e == NULL) {
- if (config != NULL) {
- NOISY(printf("New entry at %s:%d: imsi:%d/%d lang:%c%c cnt:%c%c "
+ if (kIsDebug) {
+ if (config != NULL) {
+ printf("New entry at %s:%d: imsi:%d/%d lang:%c%c cnt:%c%c "
"orien:%d touch:%d density:%d key:%d inp:%d nav:%d sz:%dx%d "
- "sw%ddp w%ddp h%ddp dir:%d\n",
+ "sw%ddp w%ddp h%ddp layout:%d\n",
sourcePos.file.string(), sourcePos.line,
config->mcc, config->mnc,
config->language[0] ? config->language[0] : '-',
@@ -3782,10 +3815,11 @@
config->smallestScreenWidthDp,
config->screenWidthDp,
config->screenHeightDp,
- config->layoutDirection));
- } else {
- NOISY(printf("New entry at %s:%d: NULL config\n",
- sourcePos.file.string(), sourcePos.line));
+ config->screenLayout);
+ } else {
+ printf("New entry at %s:%d: NULL config\n",
+ sourcePos.file.string(), sourcePos.line);
+ }
}
e = new Entry(entry, sourcePos);
c->addEntry(cdesc, e);
@@ -3891,7 +3925,7 @@
j++;
}
- return hasError ? UNKNOWN_ERROR : NO_ERROR;
+ return hasError ? STATUST(UNKNOWN_ERROR) : NO_ERROR;
}
ResourceTable::Package::Package(const String16& name, size_t packageId)
@@ -3955,9 +3989,6 @@
return UNKNOWN_ERROR;
}
- NOISY(aout << "Setting restable string pool: "
- << HexDump(data->getData(), data->getSize()) << endl);
-
status_t err = strings->setTo(data->getData(), data->getSize());
if (err == NO_ERROR) {
const size_t N = strings->size();
@@ -4181,7 +4212,7 @@
}
item->evaluating = true;
res = stringToValue(outValue, NULL, item->value, false, false, item->bagKeyId);
- NOISY(
+ if (kIsDebug) {
if (res) {
printf("getItemValue of #%08x[#%08x] (%s): type=#%08x, data=#%08x\n",
resID, attrID, String8(getEntry(resID)->getName()).string(),
@@ -4190,7 +4221,7 @@
printf("getItemValue of #%08x[#%08x]: failed\n",
resID, attrID);
}
- );
+ }
item->evaluating = false;
}
return res;
diff --git a/tools/aapt/StringPool.cpp b/tools/aapt/StringPool.cpp
index 2727b3d..a18e9f1 100644
--- a/tools/aapt/StringPool.cpp
+++ b/tools/aapt/StringPool.cpp
@@ -3,23 +3,28 @@
//
// Build resource files from raw assets.
//
-
#include "StringPool.h"
-#include "ResourceTable.h"
#include <utils/ByteOrder.h>
#include <utils/SortedVector.h>
-#include "qsort_r_compat.h"
+#include <algorithm>
+
+#include "ResourceTable.h"
+
+// SSIZE: mingw does not have signed size_t == ssize_t.
#if HAVE_PRINTF_ZD
# define ZD "%zd"
# define ZD_TYPE ssize_t
+# define SSIZE(x) x
#else
# define ZD "%ld"
# define ZD_TYPE long
+# define SSIZE(x) (signed size_t)x
#endif
-#define NOISY(x) //x
+// Set to true for noisy debug output.
+static const bool kIsDebug = false;
#if __cplusplus >= 201103L
void strcpy16_htod(char16_t* dst, const char16_t* src)
@@ -152,8 +157,10 @@
if (configTypeName != NULL) {
entry& ent = mEntries.editItemAt(eidx);
- NOISY(printf("*** adding config type name %s, was %s\n",
- configTypeName->string(), ent.configTypeName.string()));
+ if (kIsDebug) {
+ printf("*** adding config type name %s, was %s\n",
+ configTypeName->string(), ent.configTypeName.string());
+ }
if (ent.configTypeName.size() <= 0) {
ent.configTypeName = *configTypeName;
} else if (ent.configTypeName != *configTypeName) {
@@ -169,14 +176,18 @@
int cmp = ent.configs.itemAt(addPos).compareLogical(*config);
if (cmp >= 0) {
if (cmp > 0) {
- NOISY(printf("*** inserting config: %s\n", config->toString().string()));
+ if (kIsDebug) {
+ printf("*** inserting config: %s\n", config->toString().string());
+ }
ent.configs.insertAt(*config, addPos);
}
break;
}
}
if (addPos >= ent.configs.size()) {
- NOISY(printf("*** adding config: %s\n", config->toString().string()));
+ if (kIsDebug) {
+ printf("*** adding config: %s\n", config->toString().string());
+ }
ent.configs.add(*config);
}
}
@@ -193,9 +204,11 @@
ent.indices.add(pos);
}
- NOISY(printf("Adding string %s to pool: pos=%d eidx=%d vidx=%d\n",
- String8(value).string(), pos, eidx, vidx));
-
+ if (kIsDebug) {
+ printf("Adding string %s to pool: pos=%zd eidx=%zd vidx=%zd\n",
+ String8(value).string(), SSIZE(pos), SSIZE(eidx), SSIZE(vidx));
+ }
+
return pos;
}
@@ -234,12 +247,15 @@
return NO_ERROR;
}
-int StringPool::config_sort(void* state, const void* lhs, const void* rhs)
+StringPool::ConfigSorter::ConfigSorter(const StringPool& pool) : pool(pool)
{
- StringPool* pool = (StringPool*)state;
- const entry& lhe = pool->mEntries[pool->mEntryArray[*static_cast<const size_t*>(lhs)]];
- const entry& rhe = pool->mEntries[pool->mEntryArray[*static_cast<const size_t*>(rhs)]];
- return lhe.compare(rhe);
+}
+
+bool StringPool::ConfigSorter::operator()(size_t l, size_t r)
+{
+ const StringPool::entry& lhe = pool.mEntries[pool.mEntryArray[l]];
+ const StringPool::entry& rhe = pool.mEntries[pool.mEntryArray[r]];
+ return lhe.compare(rhe) < 0;
}
void StringPool::sortByConfig()
@@ -259,12 +275,14 @@
}
// Sort the array.
- NOISY(printf("SORTING STRINGS BY CONFIGURATION...\n"));
- // Vector::sort uses insertion sort, which is very slow for this data set.
- // Use quicksort instead because we don't need a stable sort here.
- qsort_r_compat(newPosToOriginalPos.editArray(), N, sizeof(size_t), this, config_sort);
- //newPosToOriginalPos.sort(config_sort, this);
- NOISY(printf("DONE SORTING STRINGS BY CONFIGURATION.\n"));
+ if (kIsDebug) {
+ printf("SORTING STRINGS BY CONFIGURATION...\n");
+ }
+ ConfigSorter sorter(*this);
+ std::sort(newPosToOriginalPos.begin(), newPosToOriginalPos.end(), sorter);
+ if (kIsDebug) {
+ printf("DONE SORTING STRINGS BY CONFIGURATION.\n");
+ }
// Create the reverse mapping from the original position in the array
// to the new position where it appears in the sorted array. This is
@@ -467,9 +485,9 @@
strncpy((char*)strings, encStr, encSize+1);
} else {
- uint16_t* strings = (uint16_t*)dat;
+ char16_t* strings = (char16_t*)dat;
- ENCODE_LENGTH(strings, sizeof(uint16_t), strSize)
+ ENCODE_LENGTH(strings, sizeof(char16_t), strSize)
strcpy16_htod(strings, ent.value);
}
@@ -561,9 +579,13 @@
for (i=0; i<ENTRIES; i++) {
entry& ent = mEntries.editItemAt(mEntryArray[i]);
*index++ = htodl(ent.offset);
- NOISY(printf("Writing entry #%d: \"%s\" ent=%d off=%d\n", i,
- String8(ent.value).string(),
- mEntryArray[i], ent.offset));
+ if (kIsDebug) {
+ printf("Writing entry #%zu: \"%s\" ent=%zu off=%zu\n",
+ i,
+ String8(ent.value).string(),
+ mEntryArray[i],
+ ent.offset);
+ }
}
// Write style index array.
@@ -579,8 +601,10 @@
{
const Vector<size_t>* indices = offsetsForString(val);
ssize_t res = indices != NULL && indices->size() > 0 ? indices->itemAt(0) : -1;
- NOISY(printf("Offset for string %s: %d (%s)\n", String8(val).string(), res,
- res >= 0 ? String8(mEntries[mEntryArray[res]].value).string() : String8()));
+ if (kIsDebug) {
+ printf("Offset for string %s: %zd (%s)\n", String8(val).string(), SSIZE(res),
+ res >= 0 ? String8(mEntries[mEntryArray[res]].value).string() : String8());
+ }
return res;
}
diff --git a/tools/aapt/StringPool.h b/tools/aapt/StringPool.h
index a9c7bec..dbe8c85 100644
--- a/tools/aapt/StringPool.h
+++ b/tools/aapt/StringPool.h
@@ -141,7 +141,14 @@
const Vector<size_t>* offsetsForString(const String16& val) const;
private:
- static int config_sort(void* state, const void* lhs, const void* rhs);
+ class ConfigSorter
+ {
+ public:
+ explicit ConfigSorter(const StringPool&);
+ bool operator()(size_t l, size_t r);
+ private:
+ const StringPool& pool;
+ };
const bool mUTF8;
diff --git a/tools/aapt/XMLNode.cpp b/tools/aapt/XMLNode.cpp
index 899fb63..b38b2ed 100644
--- a/tools/aapt/XMLNode.cpp
+++ b/tools/aapt/XMLNode.cpp
@@ -16,8 +16,26 @@
#define O_BINARY 0
#endif
-#define NOISY(x) //x
-#define NOISY_PARSE(x) //x
+// SSIZE: mingw does not have signed size_t == ssize_t.
+// STATUST: mingw does seem to redefine UNKNOWN_ERROR from our enum value, so a cast is necessary.
+#if HAVE_PRINTF_ZD
+# define SSIZE(x) x
+# define STATUST(x) x
+#else
+# define SSIZE(x) (signed size_t)x
+# define STATUST(x) (status_t)x
+#endif
+
+// Set to true for noisy debug output.
+static const bool kIsDebug = false;
+// Set to true for noisy debug output of parsing.
+static const bool kIsDebugParse = false;
+
+#if PRINT_STRING_METRICS
+static const bool kPrintStringMetrics = true;
+#else
+static const bool kPrintStringMetrics = false;
+#endif
const char* const RESOURCES_ROOT_NAMESPACE = "http://schemas.android.com/apk/res/";
const char* const RESOURCES_ANDROID_NAMESPACE = "http://schemas.android.com/apk/res/android";
@@ -56,7 +74,10 @@
size_t prefixSize;
bool isPublic = true;
if(namespaceUri.startsWith(RESOURCES_PREFIX_AUTO_PACKAGE)) {
- NOISY(printf("Using default application package: %s -> %s\n", String8(namespaceUri).string(), String8(appPackage).string()));
+ if (kIsDebug) {
+ printf("Using default application package: %s -> %s\n", String8(namespaceUri).string(),
+ String8(appPackage).string());
+ }
isPublic = true;
return appPackage;
} else if (namespaceUri.startsWith(RESOURCES_PREFIX)) {
@@ -180,7 +201,7 @@
return NO_ERROR;
}
-status_t parseStyledString(Bundle* bundle,
+status_t parseStyledString(Bundle* /* bundle */,
const char* fileName,
ResXMLTree* inXml,
const String16& endTag,
@@ -557,8 +578,10 @@
}
root->removeWhitespace(stripAll, cDataTags);
- NOISY(printf("Input XML from %s:\n", (const char*)file->getPrintableSource()));
- NOISY(root->print());
+ if (kIsDebug) {
+ printf("Input XML from %s:\n", (const char*)file->getPrintableSource());
+ root->print();
+ }
sp<AaptFile> rsc = new AaptFile(String8(), AaptGroupEntry(), String8());
status_t err = root->flatten(rsc, !keepComments, false);
if (err != NO_ERROR) {
@@ -569,8 +592,10 @@
return err;
}
- NOISY(printf("Output XML:\n"));
- NOISY(printXMLBlock(outTree));
+ if (kIsDebug) {
+ printf("Output XML:\n");
+ printXMLBlock(outTree);
+ }
return NO_ERROR;
}
@@ -850,11 +875,13 @@
} else {
mAttributeOrder.removeItem(e.index);
}
- NOISY(printf("Elem %s %s=\"%s\": set res id = 0x%08x\n",
- String8(getElementName()).string(),
- String8(mAttributes.itemAt(attrIdx).name).string(),
- String8(mAttributes.itemAt(attrIdx).string).string(),
- resId));
+ if (kIsDebug) {
+ printf("Elem %s %s=\"%s\": set res id = 0x%08x\n",
+ String8(getElementName()).string(),
+ String8(mAttributes.itemAt(attrIdx).name).string(),
+ String8(mAttributes.itemAt(attrIdx).string).string(),
+ resId);
+ }
mAttributes.editItemAt(attrIdx).nameResId = resId;
mAttributeOrder.add(resId, attrIdx);
}
@@ -965,9 +992,11 @@
e.nameResId, NULL, &defPackage, table, &ac)) {
hasErrors = true;
}
- NOISY(printf("Attr %s: type=0x%x, str=%s\n",
- String8(e.name).string(), e.value.dataType,
- String8(e.string).string()));
+ if (kIsDebug) {
+ printf("Attr %s: type=0x%x, str=%s\n",
+ String8(e.name).string(), e.value.dataType,
+ String8(e.string).string());
+ }
}
}
const size_t N = mChildren.size();
@@ -977,7 +1006,7 @@
hasErrors = true;
}
}
- return hasErrors ? UNKNOWN_ERROR : NO_ERROR;
+ return hasErrors ? STATUST(UNKNOWN_ERROR) : NO_ERROR;
}
status_t XMLNode::assignResourceIds(const sp<AaptAssets>& assets,
@@ -992,15 +1021,17 @@
for (size_t i=0; i<N; i++) {
const attribute_entry& e = mAttributes.itemAt(i);
if (e.ns.size() <= 0) continue;
- bool nsIsPublic;
+ bool nsIsPublic = true;
String16 pkg(getNamespaceResourcePackage(String16(assets->getPackage()), e.ns, &nsIsPublic));
- NOISY(printf("Elem %s %s=\"%s\": namespace(%s) %s ===> %s\n",
- String8(getElementName()).string(),
- String8(e.name).string(),
- String8(e.string).string(),
- String8(e.ns).string(),
- (nsIsPublic) ? "public" : "private",
- String8(pkg).string()));
+ if (kIsDebug) {
+ printf("Elem %s %s=\"%s\": namespace(%s) %s ===> %s\n",
+ String8(getElementName()).string(),
+ String8(e.name).string(),
+ String8(e.string).string(),
+ String8(e.ns).string(),
+ (nsIsPublic) ? "public" : "private",
+ String8(pkg).string());
+ }
if (pkg.size() <= 0) continue;
uint32_t res = table != NULL
? table->getResId(e.name, &attr, &pkg, &errorMsg, nsIsPublic)
@@ -1009,8 +1040,10 @@
attr.string(), attr.size(),
pkg.string(), pkg.size());
if (res != 0) {
- NOISY(printf("XML attribute name %s: resid=0x%08x\n",
- String8(e.name).string(), res));
+ if (kIsDebug) {
+ printf("XML attribute name %s: resid=0x%08x\n",
+ String8(e.name).string(), res);
+ }
setAttributeResID(i, res);
} else {
SourcePos(mFilename, getStartLineNumber()).error(
@@ -1028,7 +1061,7 @@
}
}
- return hasErrors ? UNKNOWN_ERROR : NO_ERROR;
+ return hasErrors ? STATUST(UNKNOWN_ERROR) : NO_ERROR;
}
sp<XMLNode> XMLNode::clone() const {
@@ -1070,18 +1103,7 @@
// Next collect all remainibng strings.
collect_strings(&strings, &resids, stripComments, stripRawValues);
-#if 0 // No longer compiles
- NOISY(printf("Found strings:\n");
- const size_t N = strings.size();
- for (size_t i=0; i<N; i++) {
- printf("%s\n", String8(strings.entryAt(i).string).string());
- }
- );
-#endif
-
sp<AaptFile> stringPool = strings.createStringBlock();
- NOISY(aout << "String pool:"
- << HexDump(stringPool->getData(), stringPool->getSize()) << endl);
ResXMLTree_header header;
memset(&header, 0, sizeof(header));
@@ -1112,17 +1134,13 @@
void* data = dest->editData();
ResXMLTree_header* hd = (ResXMLTree_header*)(((uint8_t*)data)+basePos);
- size_t size = dest->getSize()-basePos;
hd->header.size = htodl(dest->getSize()-basePos);
- NOISY(aout << "XML resource:"
- << HexDump(dest->getData(), dest->getSize()) << endl);
-
- #if PRINT_STRING_METRICS
- fprintf(stderr, "**** total xml size: %d / %d%% strings (in %s)\n",
- dest->getSize(), (stringPool->getSize()*100)/dest->getSize(),
- dest->getPath().string());
- #endif
+ if (kPrintStringMetrics) {
+ fprintf(stderr, "**** total xml size: %zu / %zu%% strings (in %s)\n",
+ dest->getSize(), (stringPool->getSize()*100)/dest->getSize(),
+ dest->getPath().string());
+ }
return NO_ERROR;
}
@@ -1195,7 +1213,9 @@
void XMLCALL
XMLNode::startNamespace(void *userData, const char *prefix, const char *uri)
{
- NOISY_PARSE(printf("Start Namespace: %s %s\n", prefix, uri));
+ if (kIsDebugParse) {
+ printf("Start Namespace: %s %s\n", prefix, uri);
+ }
ParseState* st = (ParseState*)userData;
sp<XMLNode> node = XMLNode::newNamespace(st->filename,
String16(prefix != NULL ? prefix : ""), String16(uri));
@@ -1211,7 +1231,9 @@
void XMLCALL
XMLNode::startElement(void *userData, const char *name, const char **atts)
{
- NOISY_PARSE(printf("Start Element: %s\n", name));
+ if (kIsDebugParse) {
+ printf("Start Element: %s\n", name);
+ }
ParseState* st = (ParseState*)userData;
String16 ns16, name16;
splitName(name, &ns16, &name16);
@@ -1237,7 +1259,9 @@
void XMLCALL
XMLNode::characterData(void *userData, const XML_Char *s, int len)
{
- NOISY_PARSE(printf("CDATA: \"%s\"\n", String8(s, len).string()));
+ if (kIsDebugParse) {
+ printf("CDATA: \"%s\"\n", String8(s, len).string());
+ }
ParseState* st = (ParseState*)userData;
sp<XMLNode> node = NULL;
if (st->stack.size() == 0) {
@@ -1264,7 +1288,9 @@
void XMLCALL
XMLNode::endElement(void *userData, const char *name)
{
- NOISY_PARSE(printf("End Element: %s\n", name));
+ if (kIsDebugParse) {
+ printf("End Element: %s\n", name);
+ }
ParseState* st = (ParseState*)userData;
sp<XMLNode> node = st->stack.itemAt(st->stack.size()-1);
node->setEndLineNumber(XML_GetCurrentLineNumber(st->parser));
@@ -1284,7 +1310,9 @@
XMLNode::endNamespace(void *userData, const char *prefix)
{
const char* nonNullPrefix = prefix != NULL ? prefix : "";
- NOISY_PARSE(printf("End Namespace: %s\n", prefix));
+ if (kIsDebugParse) {
+ printf("End Namespace: %s\n", prefix);
+ }
ParseState* st = (ParseState*)userData;
sp<XMLNode> node = st->stack.itemAt(st->stack.size()-1);
node->setEndLineNumber(XML_GetCurrentLineNumber(st->parser));
@@ -1296,7 +1324,9 @@
void XMLCALL
XMLNode::commentData(void *userData, const char *comment)
{
- NOISY_PARSE(printf("Comment: %s\n", comment));
+ if (kIsDebugParse) {
+ printf("Comment: %s\n", comment);
+ }
ParseState* st = (ParseState*)userData;
if (st->pendingComment.size() > 0) {
st->pendingComment.append(String16("\n"));
@@ -1393,8 +1423,10 @@
}
if (idx < 0) {
idx = outPool->add(attr.name);
- NOISY(printf("Adding attr %s (resid 0x%08x) to pool: idx=%d\n",
- String8(attr.name).string(), id, idx));
+ if (kIsDebug) {
+ printf("Adding attr %s (resid 0x%08x) to pool: idx=%zd\n",
+ String8(attr.name).string(), id, SSIZE(idx));
+ }
if (id != 0) {
while ((ssize_t)outResIds->size() <= idx) {
outResIds->add(0);
@@ -1403,8 +1435,9 @@
}
}
attr.namePoolIdx = idx;
- NOISY(printf("String %s offset=0x%08x\n",
- String8(attr.name).string(), idx));
+ if (kIsDebug) {
+ printf("String %s offset=0x%08zd\n", String8(attr.name).string(), SSIZE(idx));
+ }
}
}
diff --git a/tools/aapt/ZipEntry.cpp b/tools/aapt/ZipEntry.cpp
index b575988..f97f604 100644
--- a/tools/aapt/ZipEntry.cpp
+++ b/tools/aapt/ZipEntry.cpp
@@ -141,33 +141,15 @@
*
* Initializes the CDE and the LFH.
*/
-status_t ZipEntry::initFromExternal(const ZipFile* pZipFile,
+status_t ZipEntry::initFromExternal(const ZipFile* /* pZipFile */,
const ZipEntry* pEntry)
{
- /*
- * Copy everything in the CDE over, then fix up the hairy bits.
- */
- memcpy(&mCDE, &pEntry->mCDE, sizeof(mCDE));
-
- if (mCDE.mFileNameLength > 0) {
- mCDE.mFileName = new unsigned char[mCDE.mFileNameLength+1];
- if (mCDE.mFileName == NULL)
- return NO_MEMORY;
- strcpy((char*) mCDE.mFileName, (char*)pEntry->mCDE.mFileName);
- }
- if (mCDE.mFileCommentLength > 0) {
- mCDE.mFileComment = new unsigned char[mCDE.mFileCommentLength+1];
- if (mCDE.mFileComment == NULL)
- return NO_MEMORY;
- strcpy((char*) mCDE.mFileComment, (char*)pEntry->mCDE.mFileComment);
- }
- if (mCDE.mExtraFieldLength > 0) {
- /* we null-terminate this, though it may not be a string */
- mCDE.mExtraField = new unsigned char[mCDE.mExtraFieldLength+1];
- if (mCDE.mExtraField == NULL)
- return NO_MEMORY;
- memcpy(mCDE.mExtraField, pEntry->mCDE.mExtraField,
- mCDE.mExtraFieldLength+1);
+ mCDE = pEntry->mCDE;
+ // Check whether we got all the memory needed.
+ if ((mCDE.mFileNameLength > 0 && mCDE.mFileName == NULL) ||
+ (mCDE.mFileCommentLength > 0 && mCDE.mFileComment == NULL) ||
+ (mCDE.mExtraFieldLength > 0 && mCDE.mExtraField == NULL)) {
+ return NO_MEMORY;
}
/* construct the LFH from the CDE */
@@ -694,3 +676,60 @@
ALOGD(" comment: '%s'\n", mFileComment);
}
+/*
+ * Copy-assignment operator for CentralDirEntry.
+ */
+ZipEntry::CentralDirEntry& ZipEntry::CentralDirEntry::operator=(const ZipEntry::CentralDirEntry& src) {
+ if (this == &src) {
+ return *this;
+ }
+
+ // Free up old data.
+ delete[] mFileName;
+ delete[] mExtraField;
+ delete[] mFileComment;
+
+ // Copy scalars.
+ mVersionMadeBy = src.mVersionMadeBy;
+ mVersionToExtract = src.mVersionToExtract;
+ mGPBitFlag = src.mGPBitFlag;
+ mCompressionMethod = src.mCompressionMethod;
+ mLastModFileTime = src.mLastModFileTime;
+ mLastModFileDate = src.mLastModFileDate;
+ mCRC32 = src.mCRC32;
+ mCompressedSize = src.mCompressedSize;
+ mUncompressedSize = src.mUncompressedSize;
+ mFileNameLength = src.mFileNameLength;
+ mExtraFieldLength = src.mExtraFieldLength;
+ mFileCommentLength = src.mFileCommentLength;
+ mDiskNumberStart = src.mDiskNumberStart;
+ mInternalAttrs = src.mInternalAttrs;
+ mExternalAttrs = src.mExternalAttrs;
+ mLocalHeaderRelOffset = src.mLocalHeaderRelOffset;
+
+ // Copy strings, if necessary.
+ if (mFileNameLength > 0) {
+ mFileName = new unsigned char[mFileNameLength + 1];
+ if (mFileName != NULL)
+ strcpy((char*)mFileName, (char*)src.mFileName);
+ } else {
+ mFileName = NULL;
+ }
+ if (mFileCommentLength > 0) {
+ mFileComment = new unsigned char[mFileCommentLength + 1];
+ if (mFileComment != NULL)
+ strcpy((char*)mFileComment, (char*)src.mFileComment);
+ } else {
+ mFileComment = NULL;
+ }
+ if (mExtraFieldLength > 0) {
+ /* we null-terminate this, though it may not be a string */
+ mExtraField = new unsigned char[mExtraFieldLength + 1];
+ if (mExtraField != NULL)
+ memcpy(mExtraField, src.mExtraField, mExtraFieldLength + 1);
+ } else {
+ mExtraField = NULL;
+ }
+
+ return *this;
+}
diff --git a/tools/aapt/ZipEntry.h b/tools/aapt/ZipEntry.h
index c2f3227..287a540 100644
--- a/tools/aapt/ZipEntry.h
+++ b/tools/aapt/ZipEntry.h
@@ -298,6 +298,8 @@
status_t read(FILE* fp);
status_t write(FILE* fp);
+ CentralDirEntry& operator=(const CentralDirEntry& src);
+
// unsigned long mSignature;
unsigned short mVersionMadeBy;
unsigned short mVersionToExtract;
diff --git a/tools/aapt/ZipFile.cpp b/tools/aapt/ZipFile.cpp
index 8057068..36f4e73 100644
--- a/tools/aapt/ZipFile.cpp
+++ b/tools/aapt/ZipFile.cpp
@@ -676,8 +676,6 @@
status_t ZipFile::copyDataToFp(FILE* dstFp,
const void* data, size_t size, unsigned long* pCRC32)
{
- size_t count;
-
*pCRC32 = crc32(0L, Z_NULL, 0);
if (size > 0) {
*pCRC32 = crc32(*pCRC32, (const unsigned char*)data, size);
diff --git a/tools/aapt/qsort_r_compat.c b/tools/aapt/qsort_r_compat.c
deleted file mode 100644
index 2a8dbe8..0000000
--- a/tools/aapt/qsort_r_compat.c
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * Copyright (C) 2012 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.
- */
-
-#include <stdlib.h>
-#include "qsort_r_compat.h"
-
-/*
- * Note: This code is only used on the host, and is primarily here for
- * Mac OS compatibility. Apparently, glibc and Apple's libc disagree on
- * the parameter order for qsort_r.
- */
-
-#if HAVE_BSD_QSORT_R
-
-/*
- * BSD qsort_r parameter order is as we have defined here.
- */
-
-void qsort_r_compat(void* base, size_t nel, size_t width, void* thunk,
- int (*compar)(void*, const void* , const void*)) {
- qsort_r(base, nel, width, thunk, compar);
-}
-
-#elif HAVE_GNU_QSORT_R
-
-/*
- * GNU qsort_r parameter order places the thunk parameter last.
- */
-
-struct compar_data {
- void* thunk;
- int (*compar)(void*, const void* , const void*);
-};
-
-static int compar_wrapper(const void* a, const void* b, void* data) {
- struct compar_data* compar_data = (struct compar_data*)data;
- return compar_data->compar(compar_data->thunk, a, b);
-}
-
-void qsort_r_compat(void* base, size_t nel, size_t width, void* thunk,
- int (*compar)(void*, const void* , const void*)) {
- struct compar_data compar_data;
- compar_data.thunk = thunk;
- compar_data.compar = compar;
- qsort_r(base, nel, width, compar_wrapper, &compar_data);
-}
-
-#else
-
-/*
- * Emulate qsort_r using thread local storage to access the thunk data.
- */
-
-#include <cutils/threads.h>
-
-static thread_store_t compar_data_key = THREAD_STORE_INITIALIZER;
-
-struct compar_data {
- void* thunk;
- int (*compar)(void*, const void* , const void*);
-};
-
-static int compar_wrapper(const void* a, const void* b) {
- struct compar_data* compar_data = (struct compar_data*)thread_store_get(&compar_data_key);
- return compar_data->compar(compar_data->thunk, a, b);
-}
-
-void qsort_r_compat(void* base, size_t nel, size_t width, void* thunk,
- int (*compar)(void*, const void* , const void*)) {
- struct compar_data compar_data;
- compar_data.thunk = thunk;
- compar_data.compar = compar;
- thread_store_set(&compar_data_key, &compar_data, NULL);
- qsort(base, nel, width, compar_wrapper);
-}
-
-#endif
diff --git a/tools/aapt/qsort_r_compat.h b/tools/aapt/qsort_r_compat.h
deleted file mode 100644
index e14f999..0000000
--- a/tools/aapt/qsort_r_compat.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright (C) 2012 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.
- */
-
-/*
- * Provides a portable version of qsort_r, called qsort_r_compat, which is a
- * reentrant variant of qsort that passes a user data pointer to its comparator.
- * This implementation follows the BSD parameter convention.
- */
-
-#ifndef ___QSORT_R_COMPAT_H
-#define ___QSORT_R_COMPAT_H
-
-#include <stdlib.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-void qsort_r_compat(void* base, size_t nel, size_t width, void* thunk,
- int (*compar)(void*, const void* , const void* ));
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif // ___QSORT_R_COMPAT_H
diff --git a/tools/aidl/aidl.cpp b/tools/aidl/aidl.cpp
index 45dd23b..14c9f95 100644
--- a/tools/aidl/aidl.cpp
+++ b/tools/aidl/aidl.cpp
@@ -228,7 +228,8 @@
}
#endif
-#ifdef OS_CASE_SENSITIVE
+ // aidl assumes case-insensitivity on Mac Os and Windows.
+#if defined(__linux__)
valid = (expected == p);
#else
valid = !strcasecmp(expected.c_str(), p);
diff --git a/tools/layoutlib/bridge/resources/icons/shadow-b.png b/tools/layoutlib/bridge/resources/icons/shadow-b.png
new file mode 100644
index 0000000..68f4f4b
--- /dev/null
+++ b/tools/layoutlib/bridge/resources/icons/shadow-b.png
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/icons/shadow-bl.png b/tools/layoutlib/bridge/resources/icons/shadow-bl.png
new file mode 100644
index 0000000..ee7dbe8
--- /dev/null
+++ b/tools/layoutlib/bridge/resources/icons/shadow-bl.png
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/icons/shadow-br.png b/tools/layoutlib/bridge/resources/icons/shadow-br.png
new file mode 100644
index 0000000..c45ad77
--- /dev/null
+++ b/tools/layoutlib/bridge/resources/icons/shadow-br.png
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/icons/shadow-l.png b/tools/layoutlib/bridge/resources/icons/shadow-l.png
new file mode 100644
index 0000000..77d0bd0
--- /dev/null
+++ b/tools/layoutlib/bridge/resources/icons/shadow-l.png
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/icons/shadow-r.png b/tools/layoutlib/bridge/resources/icons/shadow-r.png
new file mode 100644
index 0000000..4af7a33
--- /dev/null
+++ b/tools/layoutlib/bridge/resources/icons/shadow-r.png
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/icons/shadow-tl.png b/tools/layoutlib/bridge/resources/icons/shadow-tl.png
new file mode 100644
index 0000000..424fb36
--- /dev/null
+++ b/tools/layoutlib/bridge/resources/icons/shadow-tl.png
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/icons/shadow-tr.png b/tools/layoutlib/bridge/resources/icons/shadow-tr.png
new file mode 100644
index 0000000..1fd0c772
--- /dev/null
+++ b/tools/layoutlib/bridge/resources/icons/shadow-tr.png
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/icons/shadow2-b.png b/tools/layoutlib/bridge/resources/icons/shadow2-b.png
new file mode 100644
index 0000000..963973e
--- /dev/null
+++ b/tools/layoutlib/bridge/resources/icons/shadow2-b.png
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/icons/shadow2-bl.png b/tools/layoutlib/bridge/resources/icons/shadow2-bl.png
new file mode 100644
index 0000000..7612487
--- /dev/null
+++ b/tools/layoutlib/bridge/resources/icons/shadow2-bl.png
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/icons/shadow2-br.png b/tools/layoutlib/bridge/resources/icons/shadow2-br.png
new file mode 100644
index 0000000..8e20252
--- /dev/null
+++ b/tools/layoutlib/bridge/resources/icons/shadow2-br.png
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/icons/shadow2-l.png b/tools/layoutlib/bridge/resources/icons/shadow2-l.png
new file mode 100644
index 0000000..2db18a0
--- /dev/null
+++ b/tools/layoutlib/bridge/resources/icons/shadow2-l.png
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/icons/shadow2-r.png b/tools/layoutlib/bridge/resources/icons/shadow2-r.png
new file mode 100644
index 0000000..8e026f1
--- /dev/null
+++ b/tools/layoutlib/bridge/resources/icons/shadow2-r.png
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/icons/shadow2-tl.png b/tools/layoutlib/bridge/resources/icons/shadow2-tl.png
new file mode 100644
index 0000000..a8045ed
--- /dev/null
+++ b/tools/layoutlib/bridge/resources/icons/shadow2-tl.png
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/icons/shadow2-tr.png b/tools/layoutlib/bridge/resources/icons/shadow2-tr.png
new file mode 100644
index 0000000..590373c
--- /dev/null
+++ b/tools/layoutlib/bridge/resources/icons/shadow2-tr.png
Binary files differ
diff --git a/tools/layoutlib/bridge/src/android/animation/AnimatorInflater_Delegate.java b/tools/layoutlib/bridge/src/android/animation/AnimatorInflater_Delegate.java
index d8a6ffc..4475fa4 100644
--- a/tools/layoutlib/bridge/src/android/animation/AnimatorInflater_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/animation/AnimatorInflater_Delegate.java
@@ -54,6 +54,6 @@
/*package*/ static ValueAnimator loadAnimator(Resources res, Theme theme,
AttributeSet attrs, ValueAnimator anim, float pathErrorScale)
throws NotFoundException {
- return anim;
+ return AnimatorInflater.loadAnimator_Original(res, theme, attrs, anim, pathErrorScale);
}
}
diff --git a/tools/layoutlib/bridge/src/android/graphics/Bitmap_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/Bitmap_Delegate.java
index f4282ad..8d24d38 100644
--- a/tools/layoutlib/bridge/src/android/graphics/Bitmap_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/graphics/Bitmap_Delegate.java
@@ -141,7 +141,6 @@
* Creates and returns a {@link Bitmap} initialized with the given stream content.
*
* @param input the stream from which to read the bitmap content
- * @param createFlags
* @param density the density associated with the bitmap
*
* @see Bitmap#isPremultiplied()
@@ -166,8 +165,7 @@
* @see Bitmap#isMutable()
* @see Bitmap#getDensity()
*/
- public static Bitmap createBitmap(BufferedImage image, boolean isMutable,
- Density density) throws IOException {
+ public static Bitmap createBitmap(BufferedImage image, boolean isMutable, Density density) {
return createBitmap(image, getPremultipliedBitmapCreateFlags(isMutable), density);
}
@@ -175,7 +173,6 @@
* Creates and returns a {@link Bitmap} initialized with the given {@link BufferedImage}
*
* @param image the bitmap content
- * @param createFlags
* @param density the density associated with the bitmap
*
* @see Bitmap#isPremultiplied()
@@ -183,7 +180,7 @@
* @see Bitmap#getDensity()
*/
public static Bitmap createBitmap(BufferedImage image, Set<BitmapCreateFlags> createFlags,
- Density density) throws IOException {
+ Density density) {
// create a delegate with the given image.
Bitmap_Delegate delegate = new Bitmap_Delegate(image, Config.ARGB_8888);
diff --git a/tools/layoutlib/bridge/src/android/graphics/Matrix_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/Matrix_Delegate.java
index f42f48f..1105c7b 100644
--- a/tools/layoutlib/bridge/src/android/graphics/Matrix_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/graphics/Matrix_Delegate.java
@@ -661,9 +661,8 @@
float[] src = new float[] { radius, 0.f, 0.f, radius };
d.mapVectors(src, 0, src, 0, 2);
- float l1 = getPointLength(src, 0);
- float l2 = getPointLength(src, 2);
-
+ float l1 = (float) Math.hypot(src[0], src[1]);
+ float l2 = (float) Math.hypot(src[2], src[3]);
return (float) Math.sqrt(l1 * l2);
}
@@ -918,10 +917,6 @@
}
}
- private static float getPointLength(float[] src, int index) {
- return (float) Math.sqrt(src[index] * src[index] + src[index + 1] * src[index + 1]);
- }
-
/**
* multiply two matrices and store them in a 3rd.
* <p/>This in effect does dest = a*b
diff --git a/tools/layoutlib/bridge/src/android/graphics/Paint_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/Paint_Delegate.java
index 7b07404..8ffd1d8 100644
--- a/tools/layoutlib/bridge/src/android/graphics/Paint_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/graphics/Paint_Delegate.java
@@ -251,7 +251,7 @@
@LayoutlibDelegate
/*package*/ static int getFlags(Paint thisPaint) {
// get the delegate from the native int.
- Paint_Delegate delegate = sManager.getDelegate(thisPaint.mNativePaint);
+ Paint_Delegate delegate = sManager.getDelegate(thisPaint.getNativeInstance());
if (delegate == null) {
return 0;
}
@@ -264,7 +264,7 @@
@LayoutlibDelegate
/*package*/ static void setFlags(Paint thisPaint, int flags) {
// get the delegate from the native int.
- Paint_Delegate delegate = sManager.getDelegate(thisPaint.mNativePaint);
+ Paint_Delegate delegate = sManager.getDelegate(thisPaint.getNativeInstance());
if (delegate == null) {
return;
}
@@ -280,7 +280,7 @@
@LayoutlibDelegate
/*package*/ static int getHinting(Paint thisPaint) {
// get the delegate from the native int.
- Paint_Delegate delegate = sManager.getDelegate(thisPaint.mNativePaint);
+ Paint_Delegate delegate = sManager.getDelegate(thisPaint.getNativeInstance());
if (delegate == null) {
return Paint.HINTING_ON;
}
@@ -291,7 +291,7 @@
@LayoutlibDelegate
/*package*/ static void setHinting(Paint thisPaint, int mode) {
// get the delegate from the native int.
- Paint_Delegate delegate = sManager.getDelegate(thisPaint.mNativePaint);
+ Paint_Delegate delegate = sManager.getDelegate(thisPaint.getNativeInstance());
if (delegate == null) {
return;
}
@@ -337,7 +337,7 @@
@LayoutlibDelegate
/*package*/ static int getColor(Paint thisPaint) {
// get the delegate from the native int.
- Paint_Delegate delegate = sManager.getDelegate(thisPaint.mNativePaint);
+ Paint_Delegate delegate = sManager.getDelegate(thisPaint.getNativeInstance());
if (delegate == null) {
return 0;
}
@@ -348,7 +348,7 @@
@LayoutlibDelegate
/*package*/ static void setColor(Paint thisPaint, int color) {
// get the delegate from the native int.
- Paint_Delegate delegate = sManager.getDelegate(thisPaint.mNativePaint);
+ Paint_Delegate delegate = sManager.getDelegate(thisPaint.getNativeInstance());
if (delegate == null) {
return;
}
@@ -359,7 +359,7 @@
@LayoutlibDelegate
/*package*/ static int getAlpha(Paint thisPaint) {
// get the delegate from the native int.
- Paint_Delegate delegate = sManager.getDelegate(thisPaint.mNativePaint);
+ Paint_Delegate delegate = sManager.getDelegate(thisPaint.getNativeInstance());
if (delegate == null) {
return 0;
}
@@ -370,7 +370,7 @@
@LayoutlibDelegate
/*package*/ static void setAlpha(Paint thisPaint, int a) {
// get the delegate from the native int.
- Paint_Delegate delegate = sManager.getDelegate(thisPaint.mNativePaint);
+ Paint_Delegate delegate = sManager.getDelegate(thisPaint.getNativeInstance());
if (delegate == null) {
return;
}
@@ -381,7 +381,7 @@
@LayoutlibDelegate
/*package*/ static float getStrokeWidth(Paint thisPaint) {
// get the delegate from the native int.
- Paint_Delegate delegate = sManager.getDelegate(thisPaint.mNativePaint);
+ Paint_Delegate delegate = sManager.getDelegate(thisPaint.getNativeInstance());
if (delegate == null) {
return 1.f;
}
@@ -392,7 +392,7 @@
@LayoutlibDelegate
/*package*/ static void setStrokeWidth(Paint thisPaint, float width) {
// get the delegate from the native int.
- Paint_Delegate delegate = sManager.getDelegate(thisPaint.mNativePaint);
+ Paint_Delegate delegate = sManager.getDelegate(thisPaint.getNativeInstance());
if (delegate == null) {
return;
}
@@ -403,7 +403,7 @@
@LayoutlibDelegate
/*package*/ static float getStrokeMiter(Paint thisPaint) {
// get the delegate from the native int.
- Paint_Delegate delegate = sManager.getDelegate(thisPaint.mNativePaint);
+ Paint_Delegate delegate = sManager.getDelegate(thisPaint.getNativeInstance());
if (delegate == null) {
return 1.f;
}
@@ -414,7 +414,7 @@
@LayoutlibDelegate
/*package*/ static void setStrokeMiter(Paint thisPaint, float miter) {
// get the delegate from the native int.
- Paint_Delegate delegate = sManager.getDelegate(thisPaint.mNativePaint);
+ Paint_Delegate delegate = sManager.getDelegate(thisPaint.getNativeInstance());
if (delegate == null) {
return;
}
@@ -441,14 +441,14 @@
@LayoutlibDelegate
/*package*/ static boolean isElegantTextHeight(Paint thisPaint) {
// get the delegate from the native int.
- Paint_Delegate delegate = sManager.getDelegate(thisPaint.mNativePaint);
+ Paint_Delegate delegate = sManager.getDelegate(thisPaint.getNativeInstance());
return delegate != null && delegate.mFontVariant == FontVariant.ELEGANT;
}
@LayoutlibDelegate
/*package*/ static void setElegantTextHeight(Paint thisPaint, boolean elegant) {
// get the delegate from the native int.
- Paint_Delegate delegate = sManager.getDelegate(thisPaint.mNativePaint);
+ Paint_Delegate delegate = sManager.getDelegate(thisPaint.getNativeInstance());
if (delegate == null) {
return;
}
@@ -459,7 +459,7 @@
@LayoutlibDelegate
/*package*/ static float getTextSize(Paint thisPaint) {
// get the delegate from the native int.
- Paint_Delegate delegate = sManager.getDelegate(thisPaint.mNativePaint);
+ Paint_Delegate delegate = sManager.getDelegate(thisPaint.getNativeInstance());
if (delegate == null) {
return 1.f;
}
@@ -470,7 +470,7 @@
@LayoutlibDelegate
/*package*/ static void setTextSize(Paint thisPaint, float textSize) {
// get the delegate from the native int.
- Paint_Delegate delegate = sManager.getDelegate(thisPaint.mNativePaint);
+ Paint_Delegate delegate = sManager.getDelegate(thisPaint.getNativeInstance());
if (delegate == null) {
return;
}
@@ -482,7 +482,7 @@
@LayoutlibDelegate
/*package*/ static float getTextScaleX(Paint thisPaint) {
// get the delegate from the native int.
- Paint_Delegate delegate = sManager.getDelegate(thisPaint.mNativePaint);
+ Paint_Delegate delegate = sManager.getDelegate(thisPaint.getNativeInstance());
if (delegate == null) {
return 1.f;
}
@@ -493,7 +493,7 @@
@LayoutlibDelegate
/*package*/ static void setTextScaleX(Paint thisPaint, float scaleX) {
// get the delegate from the native int.
- Paint_Delegate delegate = sManager.getDelegate(thisPaint.mNativePaint);
+ Paint_Delegate delegate = sManager.getDelegate(thisPaint.getNativeInstance());
if (delegate == null) {
return;
}
@@ -505,7 +505,7 @@
@LayoutlibDelegate
/*package*/ static float getTextSkewX(Paint thisPaint) {
// get the delegate from the native int.
- Paint_Delegate delegate = sManager.getDelegate(thisPaint.mNativePaint);
+ Paint_Delegate delegate = sManager.getDelegate(thisPaint.getNativeInstance());
if (delegate == null) {
return 1.f;
}
@@ -516,7 +516,7 @@
@LayoutlibDelegate
/*package*/ static void setTextSkewX(Paint thisPaint, float skewX) {
// get the delegate from the native int.
- Paint_Delegate delegate = sManager.getDelegate(thisPaint.mNativePaint);
+ Paint_Delegate delegate = sManager.getDelegate(thisPaint.getNativeInstance());
if (delegate == null) {
return;
}
@@ -528,7 +528,7 @@
@LayoutlibDelegate
/*package*/ static float ascent(Paint thisPaint) {
// get the delegate
- Paint_Delegate delegate = sManager.getDelegate(thisPaint.mNativePaint);
+ Paint_Delegate delegate = sManager.getDelegate(thisPaint.getNativeInstance());
if (delegate == null) {
return 0;
}
@@ -545,7 +545,7 @@
@LayoutlibDelegate
/*package*/ static float descent(Paint thisPaint) {
// get the delegate
- Paint_Delegate delegate = sManager.getDelegate(thisPaint.mNativePaint);
+ Paint_Delegate delegate = sManager.getDelegate(thisPaint.getNativeInstance());
if (delegate == null) {
return 0;
}
@@ -562,7 +562,7 @@
@LayoutlibDelegate
/*package*/ static float getFontMetrics(Paint thisPaint, FontMetrics metrics) {
// get the delegate
- Paint_Delegate delegate = sManager.getDelegate(thisPaint.mNativePaint);
+ Paint_Delegate delegate = sManager.getDelegate(thisPaint.getNativeInstance());
if (delegate == null) {
return 0;
}
@@ -573,7 +573,7 @@
@LayoutlibDelegate
/*package*/ static int getFontMetricsInt(Paint thisPaint, FontMetricsInt fmi) {
// get the delegate
- Paint_Delegate delegate = sManager.getDelegate(thisPaint.mNativePaint);
+ Paint_Delegate delegate = sManager.getDelegate(thisPaint.getNativeInstance());
if (delegate == null) {
return 0;
}
@@ -599,7 +599,7 @@
/*package*/ static float native_measureText(Paint thisPaint, char[] text, int index,
int count, int bidiFlags) {
// get the delegate
- Paint_Delegate delegate = sManager.getDelegate(thisPaint.mNativePaint);
+ Paint_Delegate delegate = sManager.getDelegate(thisPaint.getNativeInstance());
if (delegate == null) {
return 0;
}
@@ -1232,7 +1232,7 @@
private static void setFlag(Paint thisPaint, int flagMask, boolean flagValue) {
// get the delegate from the native int.
- Paint_Delegate delegate = sManager.getDelegate(thisPaint.mNativePaint);
+ Paint_Delegate delegate = sManager.getDelegate(thisPaint.getNativeInstance());
if (delegate == null) {
return;
}
diff --git a/tools/layoutlib/bridge/src/android/graphics/RadialGradient_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/RadialGradient_Delegate.java
index 80179ee..eb29835 100644
--- a/tools/layoutlib/bridge/src/android/graphics/RadialGradient_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/graphics/RadialGradient_Delegate.java
@@ -184,7 +184,7 @@
float _x = pt2[0];
float _y = pt2[1];
- float distance = (float) Math.sqrt(_x * _x + _y * _y);
+ float distance = (float) Math.hypot(_x, _y);
data[index++] = getGradientColor(distance / mRadius);
}
diff --git a/tools/layoutlib/bridge/src/android/text/GreedyLineBreaker.java b/tools/layoutlib/bridge/src/android/text/GreedyLineBreaker.java
new file mode 100644
index 0000000..24e4b54
--- /dev/null
+++ b/tools/layoutlib/bridge/src/android/text/GreedyLineBreaker.java
@@ -0,0 +1,193 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.text;
+
+import com.android.annotations.NonNull;
+
+import android.text.Primitive.PrimitiveType;
+import android.text.StaticLayout.LineBreaks;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import static android.text.Primitive.PrimitiveType.PENALTY_INFINITY;
+
+// Based on the native implementation of GreedyLineBreaker in
+// frameworks/base/core/jni/android_text_StaticLayout.cpp revision b808260
+public class GreedyLineBreaker extends LineBreaker {
+
+ public GreedyLineBreaker(@NonNull List<Primitive> primitives, @NonNull LineWidth lineWidth,
+ @NonNull TabStops tabStops) {
+ super(primitives, lineWidth, tabStops);
+ }
+
+ @Override
+ public void computeBreaks(LineBreaks lineBreaks) {
+ BreakInfo breakInfo = new BreakInfo();
+ int lineNum = 0;
+ float width = 0, printedWidth = 0;
+ boolean breakFound = false, goodBreakFound = false;
+ int breakIndex = 0, goodBreakIndex = 0;
+ float breakWidth = 0, goodBreakWidth = 0;
+ int firstTabIndex = Integer.MAX_VALUE;
+
+ float maxWidth = mLineWidth.getLineWidth(lineNum);
+
+ int numPrimitives = mPrimitives.size();
+ // greedily fit as many characters as possible on each line
+ // loop over all primitives, and choose the best break point
+ // (if possible, a break point without splitting a word)
+ // after going over the maximum length
+ for (int i = 0; i < numPrimitives; i++) {
+ Primitive p = mPrimitives.get(i);
+
+ // update the current line width
+ if (p.type == PrimitiveType.BOX || p.type == PrimitiveType.GLUE) {
+ width += p.width;
+ if (p.type == PrimitiveType.BOX) {
+ printedWidth = width;
+ }
+ } else if (p.type == PrimitiveType.VARIABLE) {
+ width = mTabStops.width(width);
+ // keep track of first tab character in the region we are examining
+ // so we can determine whether or not a line contains a tab
+ firstTabIndex = Math.min(firstTabIndex, i);
+ }
+
+ // find the best break point for the characters examined so far
+ if (printedWidth > maxWidth) {
+ //noinspection StatementWithEmptyBody
+ if (breakFound || goodBreakFound) {
+ if (goodBreakFound) {
+ // a true line break opportunity existed in the characters examined so far,
+ // so there is no need to split a word
+ i = goodBreakIndex; // no +1 because of i++
+ lineNum++;
+ maxWidth = mLineWidth.getLineWidth(lineNum);
+ breakInfo.mBreaksList.add(mPrimitives.get(goodBreakIndex).location);
+ breakInfo.mWidthsList.add(goodBreakWidth);
+ breakInfo.mFlagsList.add(firstTabIndex < goodBreakIndex);
+ firstTabIndex = Integer.MAX_VALUE;
+ } else {
+ // must split a word because there is no other option
+ i = breakIndex; // no +1 because of i++
+ lineNum++;
+ maxWidth = mLineWidth.getLineWidth(lineNum);
+ breakInfo.mBreaksList.add(mPrimitives.get(breakIndex).location);
+ breakInfo.mWidthsList.add(breakWidth);
+ breakInfo.mFlagsList.add(firstTabIndex < breakIndex);
+ firstTabIndex = Integer.MAX_VALUE;
+ }
+ printedWidth = width = 0;
+ goodBreakFound = breakFound = false;
+ goodBreakWidth = breakWidth = 0;
+ continue;
+ } else {
+ // no choice, keep going... must make progress by putting at least one
+ // character on a line, even if part of that character is cut off --
+ // there is no other option
+ }
+ }
+
+ // update possible break points
+ if (p.type == PrimitiveType.PENALTY &&
+ p.penalty < PENALTY_INFINITY) {
+ // this does not handle penalties with width
+
+ // handle forced line break
+ if (p.penalty == -PENALTY_INFINITY) {
+ lineNum++;
+ maxWidth = mLineWidth.getLineWidth(lineNum);
+ breakInfo.mBreaksList.add(p.location);
+ breakInfo.mWidthsList.add(printedWidth);
+ breakInfo.mFlagsList.add(firstTabIndex < i);
+ firstTabIndex = Integer.MAX_VALUE;
+ printedWidth = width = 0;
+ goodBreakFound = breakFound = false;
+ goodBreakWidth = breakWidth = 0;
+ continue;
+ }
+ if (i > breakIndex && (printedWidth <= maxWidth || !breakFound)) {
+ breakFound = true;
+ breakIndex = i;
+ breakWidth = printedWidth;
+ }
+ if (i > goodBreakIndex && printedWidth <= maxWidth) {
+ goodBreakFound = true;
+ goodBreakIndex = i;
+ goodBreakWidth = printedWidth;
+ }
+ } else if (p.type == PrimitiveType.WORD_BREAK) {
+ // only do this if necessary -- we don't want to break words
+ // when possible, but sometimes it is unavoidable
+ if (i > breakIndex && (printedWidth <= maxWidth || !breakFound)) {
+ breakFound = true;
+ breakIndex = i;
+ breakWidth = printedWidth;
+ }
+ }
+ }
+
+ if (breakFound || goodBreakFound) {
+ // output last break if there are more characters to output
+ if (goodBreakFound) {
+ breakInfo.mBreaksList.add(mPrimitives.get(goodBreakIndex).location);
+ breakInfo.mWidthsList.add(goodBreakWidth);
+ breakInfo.mFlagsList.add(firstTabIndex < goodBreakIndex);
+ } else {
+ breakInfo.mBreaksList.add(mPrimitives.get(breakIndex).location);
+ breakInfo.mWidthsList.add(breakWidth);
+ breakInfo.mFlagsList.add(firstTabIndex < breakIndex);
+ }
+ }
+ breakInfo.copyTo(lineBreaks);
+ }
+
+ private static class BreakInfo {
+ List<Integer> mBreaksList = new ArrayList<Integer>();
+ List<Float> mWidthsList = new ArrayList<Float>();
+ List<Boolean> mFlagsList = new ArrayList<Boolean>();
+
+ public void copyTo(LineBreaks lineBreaks) {
+ if (lineBreaks.breaks.length != mBreaksList.size()) {
+ lineBreaks.breaks = new int[mBreaksList.size()];
+ lineBreaks.widths = new float[mWidthsList.size()];
+ lineBreaks.flags = new boolean[mFlagsList.size()];
+ }
+
+ int i = 0;
+ for (int b : mBreaksList) {
+ lineBreaks.breaks[i] = b;
+ i++;
+ }
+ i = 0;
+ for (float b : mWidthsList) {
+ lineBreaks.widths[i] = b;
+ i++;
+ }
+ i = 0;
+ for (boolean b : mFlagsList) {
+ lineBreaks.flags[i] = b;
+ i++;
+ }
+
+ mBreaksList = null;
+ mWidthsList = null;
+ mFlagsList = null;
+ }
+ }
+}
diff --git a/tools/layoutlib/bridge/src/android/text/LineBreaker.java b/tools/layoutlib/bridge/src/android/text/LineBreaker.java
new file mode 100644
index 0000000..8be3635
--- /dev/null
+++ b/tools/layoutlib/bridge/src/android/text/LineBreaker.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.text;
+
+import android.text.StaticLayout.LineBreaks;
+import com.android.annotations.NonNull;
+
+import java.util.Collections;
+import java.util.List;
+
+// Based on the native implementation of LineBreaker in
+// frameworks/base/core/jni/android_text_StaticLayout.cpp revision b808260
+public abstract class LineBreaker {
+
+ protected final @NonNull List<Primitive> mPrimitives;
+ protected final @NonNull LineWidth mLineWidth;
+ protected final @NonNull TabStops mTabStops;
+
+ public LineBreaker(@NonNull List<Primitive> primitives, @NonNull LineWidth lineWidth,
+ @NonNull TabStops tabStops) {
+ mPrimitives = Collections.unmodifiableList(primitives);
+ mLineWidth = lineWidth;
+ mTabStops = tabStops;
+ }
+
+ @NonNull
+ public abstract void computeBreaks(@NonNull LineBreaks breakInfo);
+}
diff --git a/tools/layoutlib/bridge/src/android/text/LineWidth.java b/tools/layoutlib/bridge/src/android/text/LineWidth.java
new file mode 100644
index 0000000..2ea886d
--- /dev/null
+++ b/tools/layoutlib/bridge/src/android/text/LineWidth.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.text;
+
+// Based on the native implementation of LineWidth in
+// frameworks/base/core/jni/android_text_StaticLayout.cpp revision b808260
+public class LineWidth {
+ private final float mFirstWidth;
+ private final int mFirstWidthLineCount;
+ private float mRestWidth;
+
+ public LineWidth(float firstWidth, int firstWidthLineCount, float restWidth) {
+ mFirstWidth = firstWidth;
+ mFirstWidthLineCount = firstWidthLineCount;
+ mRestWidth = restWidth;
+ }
+
+ public float getLineWidth(int line) {
+ return (line < mFirstWidthLineCount) ? mFirstWidth : mRestWidth;
+ }
+}
diff --git a/tools/layoutlib/bridge/src/android/text/OptimizingLineBreaker.java b/tools/layoutlib/bridge/src/android/text/OptimizingLineBreaker.java
new file mode 100644
index 0000000..d5d7798
--- /dev/null
+++ b/tools/layoutlib/bridge/src/android/text/OptimizingLineBreaker.java
@@ -0,0 +1,262 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.text;
+
+import com.android.annotations.NonNull;
+
+import android.text.Primitive.PrimitiveType;
+import android.text.StaticLayout.LineBreaks;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.ListIterator;
+
+import static android.text.Primitive.PrimitiveType.PENALTY_INFINITY;
+
+
+// Based on the native implementation of OptimizingLineBreaker in
+// frameworks/base/core/jni/android_text_StaticLayout.cpp revision b808260
+/**
+ * A more complex version of line breaking where we try to prevent the right edge from being too
+ * jagged.
+ */
+public class OptimizingLineBreaker extends LineBreaker {
+
+ public OptimizingLineBreaker(@NonNull List<Primitive> primitives, @NonNull LineWidth lineWidth,
+ @NonNull TabStops tabStops) {
+ super(primitives, lineWidth, tabStops);
+ }
+
+ @Override
+ public void computeBreaks(@NonNull LineBreaks breakInfo) {
+ int numBreaks = mPrimitives.size();
+ assert numBreaks > 0;
+ if (numBreaks == 1) {
+ // This can be true only if it's an empty paragraph.
+ Primitive p = mPrimitives.get(0);
+ assert p.type == PrimitiveType.PENALTY;
+ breakInfo.breaks = new int[]{0};
+ breakInfo.widths = new float[]{p.width};
+ breakInfo.flags = new boolean[]{false};
+ return;
+ }
+ Node[] opt = new Node[numBreaks];
+ opt[0] = new Node(-1, 0, 0, 0, false);
+ opt[numBreaks - 1] = new Node(-1, 0, 0, 0, false);
+
+ ArrayList<Integer> active = new ArrayList<Integer>();
+ active.add(0);
+ int lastBreak = 0;
+ for (int i = 0; i < numBreaks; i++) {
+ Primitive p = mPrimitives.get(i);
+ if (p.type == PrimitiveType.PENALTY) {
+ boolean finalBreak = (i + 1 == numBreaks);
+ Node bestBreak = null;
+
+ for (ListIterator<Integer> it = active.listIterator(); it.hasNext();
+ /* incrementing done in loop */) {
+ int pos = it.next();
+ int lines = opt[pos].mPrevCount;
+ float maxWidth = mLineWidth.getLineWidth(lines);
+ // we have to compute metrics every time --
+ // we can't really pre-compute this stuff and just deal with breaks
+ // because of the way tab characters work, this makes it computationally
+ // harder, but this way, we can still optimize while treating tab characters
+ // correctly
+ LineMetrics lineMetrics = computeMetrics(pos, i);
+ if (lineMetrics.mPrintedWidth <= maxWidth) {
+ float demerits = computeDemerits(maxWidth, lineMetrics.mPrintedWidth,
+ finalBreak, p.penalty) + opt[pos].mDemerits;
+ if (bestBreak == null || demerits < bestBreak.mDemerits) {
+ if (bestBreak == null) {
+ bestBreak = new Node(pos, opt[pos].mPrevCount + 1, demerits,
+ lineMetrics.mPrintedWidth, lineMetrics.mHasTabs);
+ } else {
+ bestBreak.mPrev = pos;
+ bestBreak.mPrevCount = opt[pos].mPrevCount + 1;
+ bestBreak.mDemerits = demerits;
+ bestBreak.mWidth = lineMetrics.mPrintedWidth;
+ bestBreak.mHasTabs = lineMetrics.mHasTabs;
+ }
+ }
+ } else {
+ it.remove();
+ }
+ }
+ if (p.penalty == -PENALTY_INFINITY) {
+ active.clear();
+ }
+ if (bestBreak != null) {
+ opt[i] = bestBreak;
+ active.add(i);
+ lastBreak = i;
+ }
+ if (active.isEmpty()) {
+ // we can't give up!
+ LineMetrics lineMetrics = new LineMetrics();
+ int lines = opt[lastBreak].mPrevCount;
+ float maxWidth = mLineWidth.getLineWidth(lines);
+ int breakIndex = desperateBreak(lastBreak, numBreaks, maxWidth, lineMetrics);
+ opt[breakIndex] = new Node(lastBreak, lines + 1, 0 /*doesn't matter*/,
+ lineMetrics.mWidth, lineMetrics.mHasTabs);
+ active.add(breakIndex);
+ lastBreak = breakIndex;
+ i = breakIndex; // incremented by i++
+ }
+ }
+ }
+
+ int idx = numBreaks - 1;
+ int count = opt[idx].mPrevCount;
+ resize(breakInfo, count);
+ while (opt[idx].mPrev != -1) {
+ count--;
+ assert count >=0;
+
+ breakInfo.breaks[count] = mPrimitives.get(idx).location;
+ breakInfo.widths[count] = opt[idx].mWidth;
+ breakInfo.flags [count] = opt[idx].mHasTabs;
+ idx = opt[idx].mPrev;
+ }
+ }
+
+ private static void resize(LineBreaks lineBreaks, int size) {
+ if (lineBreaks.breaks.length == size) {
+ return;
+ }
+ int[] breaks = new int[size];
+ float[] widths = new float[size];
+ boolean[] flags = new boolean[size];
+
+ int toCopy = Math.min(size, lineBreaks.breaks.length);
+ System.arraycopy(lineBreaks.breaks, 0, breaks, 0, toCopy);
+ System.arraycopy(lineBreaks.widths, 0, widths, 0, toCopy);
+ System.arraycopy(lineBreaks.flags, 0, flags, 0, toCopy);
+
+ lineBreaks.breaks = breaks;
+ lineBreaks.widths = widths;
+ lineBreaks.flags = flags;
+ }
+
+ @NonNull
+ private LineMetrics computeMetrics(int start, int end) {
+ boolean f = false;
+ float w = 0, pw = 0;
+ for (int i = start; i < end; i++) {
+ Primitive p = mPrimitives.get(i);
+ if (p.type == PrimitiveType.BOX || p.type == PrimitiveType.GLUE) {
+ w += p.width;
+ if (p.type == PrimitiveType.BOX) {
+ pw = w;
+ }
+ } else if (p.type == PrimitiveType.VARIABLE) {
+ w = mTabStops.width(w);
+ f = true;
+ }
+ }
+ return new LineMetrics(w, pw, f);
+ }
+
+ private static float computeDemerits(float maxWidth, float width, boolean finalBreak,
+ float penalty) {
+ float deviation = finalBreak ? 0 : maxWidth - width;
+ return (deviation * deviation) + penalty;
+ }
+
+ /**
+ * @return the last break position or -1 if failed.
+ */
+ @SuppressWarnings("ConstantConditions") // method too complex to be analyzed.
+ private int desperateBreak(int start, int limit, float maxWidth,
+ @NonNull LineMetrics lineMetrics) {
+ float w = 0, pw = 0;
+ boolean breakFound = false;
+ int breakIndex = 0, firstTabIndex = Integer.MAX_VALUE;
+ for (int i = start; i < limit; i++) {
+ Primitive p = mPrimitives.get(i);
+
+ if (p.type == PrimitiveType.BOX || p.type == PrimitiveType.GLUE) {
+ w += p.width;
+ if (p.type == PrimitiveType.BOX) {
+ pw = w;
+ }
+ } else if (p.type == PrimitiveType.VARIABLE) {
+ w = mTabStops.width(w);
+ firstTabIndex = Math.min(firstTabIndex, i);
+ }
+
+ if (pw > maxWidth && breakFound) {
+ break;
+ }
+
+ // must make progress
+ if (i > start &&
+ (p.type == PrimitiveType.PENALTY || p.type == PrimitiveType.WORD_BREAK)) {
+ breakFound = true;
+ breakIndex = i;
+ }
+ }
+
+ if (breakFound) {
+ lineMetrics.mWidth = w;
+ lineMetrics.mPrintedWidth = pw;
+ lineMetrics.mHasTabs = (start <= firstTabIndex && firstTabIndex < breakIndex);
+ return breakIndex;
+ } else {
+ return -1;
+ }
+ }
+
+ private static class LineMetrics {
+ /** Actual width of the line. */
+ float mWidth;
+ /** Width of the line minus trailing whitespace. */
+ float mPrintedWidth;
+ boolean mHasTabs;
+
+ public LineMetrics() {
+ }
+
+ public LineMetrics(float width, float printedWidth, boolean hasTabs) {
+ mWidth = width;
+ mPrintedWidth = printedWidth;
+ mHasTabs = hasTabs;
+ }
+ }
+
+ /**
+ * A struct to store the info about a break.
+ */
+ @SuppressWarnings("SpellCheckingInspection") // For the word struct.
+ private static class Node {
+ // -1 for the first node.
+ int mPrev;
+ // number of breaks so far.
+ int mPrevCount;
+ float mDemerits;
+ float mWidth;
+ boolean mHasTabs;
+
+ public Node(int prev, int prevCount, float demerits, float width, boolean hasTabs) {
+ mPrev = prev;
+ mPrevCount = prevCount;
+ mDemerits = demerits;
+ mWidth = width;
+ mHasTabs = hasTabs;
+ }
+ }
+}
diff --git a/tools/layoutlib/bridge/src/android/text/Primitive.java b/tools/layoutlib/bridge/src/android/text/Primitive.java
new file mode 100644
index 0000000..ce77601
--- /dev/null
+++ b/tools/layoutlib/bridge/src/android/text/Primitive.java
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.text;
+
+import com.android.annotations.NonNull;
+
+// Based on the native implementation of Primitive in
+// frameworks/base/core/jni/android_text_StaticLayout.cpp revision b808260
+public class Primitive {
+ public final @NonNull PrimitiveType type;
+ public final int location;
+ // The following fields don't make sense for all types.
+ // Box and Glue have width only.
+ // Penalty has both width and penalty.
+ // Word_break has penalty only.
+ public final float width;
+ public final float penalty;
+
+ /**
+ * Use {@code PrimitiveType#getNewPrimitive()}
+ */
+ private Primitive(@NonNull PrimitiveType type, int location, float width, float penalty) {
+ this.type = type;
+ this.location = location;
+ this.width = width;
+ this.penalty = penalty;
+ }
+
+ public static enum PrimitiveType {
+ /**
+ * Something with a constant width that is to be typeset - like a character.
+ */
+ BOX,
+ /**
+ * Blank space with fixed width.
+ */
+ GLUE,
+ /**
+ * Aesthetic cost indicating how desirable breaking at this point will be. A penalty of
+ * {@link #PENALTY_INFINITY} means a forced non-break, whereas a penalty of negative
+ * {@code #PENALTY_INFINITY} means a forced break.
+ * <p/>
+ * Currently, it only stores penalty with values 0 or -infinity.
+ */
+ PENALTY,
+ /**
+ * For tabs - variable width space.
+ */
+ VARIABLE,
+ /**
+ * Possible breakpoints within a word. Think of this as a high cost {@link #PENALTY}.
+ */
+ WORD_BREAK;
+
+ public Primitive getNewPrimitive(int location) {
+ assert this == VARIABLE;
+ return new Primitive(this, location, 0f, 0f);
+ }
+
+ public Primitive getNewPrimitive(int location, float value) {
+ assert this == BOX || this == GLUE || this == WORD_BREAK;
+ if (this == BOX || this == GLUE) {
+ return new Primitive(this, location, value, 0f);
+ } else {
+ return new Primitive(this, location, 0f, value);
+ }
+ }
+
+ public Primitive getNewPrimitive(int location, float width, float penalty) {
+ assert this == PENALTY;
+ return new Primitive(this, location, width, penalty);
+ }
+
+ // forced non-break, negative infinity is forced break.
+ public static final float PENALTY_INFINITY = 1e7f;
+ }
+}
+
diff --git a/tools/layoutlib/bridge/src/android/text/StaticLayout_Delegate.java b/tools/layoutlib/bridge/src/android/text/StaticLayout_Delegate.java
index 5a467b2..c48b771 100644
--- a/tools/layoutlib/bridge/src/android/text/StaticLayout_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/text/StaticLayout_Delegate.java
@@ -1,55 +1,99 @@
package android.text;
+import com.android.annotations.NonNull;
import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-import java.text.CharacterIterator;
-import java.util.Arrays;
-import java.util.Locale;
+import android.text.StaticLayout.LineBreaks;
+import android.text.Primitive.PrimitiveType;
-import com.ibm.icu.lang.UCharacter;
+import java.util.ArrayList;
+import java.util.List;
+
import com.ibm.icu.text.BreakIterator;
import com.ibm.icu.util.ULocale;
import javax.swing.text.Segment;
/**
* Delegate that provides implementation for native methods in {@link android.text.StaticLayout}
- *
- * Through the layoutlib_create tool, selected methods of Handler have been replaced
- * by calls to methods of the same name in this delegate class.
- *
+ * <p/>
+ * Through the layoutlib_create tool, selected methods of Handler have been replaced by calls to
+ * methods of the same name in this delegate class.
*/
public class StaticLayout_Delegate {
- /**
- * Fills the recycle array with positions that are suitable to break the text at. The array
- * must be terminated by '-1'.
- */
+ private static final char CHAR_SPACE = 0x20;
+ private static final char CHAR_TAB = 0x09;
+ private static final char CHAR_NEWLINE = 0x0A;
+ private static final char CHAR_ZWSP = 0x200B; // Zero width space.
+
@LayoutlibDelegate
- /*package*/ static int[] nLineBreakOpportunities(String locale, char[] text, int length,
- int[] recycle) {
- BreakIterator iterator = BreakIterator.getLineInstance(new ULocale(locale));
- Segment segment = new Segment(text, 0, length);
- iterator.setText(segment);
- if (recycle == null) {
- // Because 42 is the answer to everything.
- recycle = new int[42];
+ /*package*/ static int nComputeLineBreaks(String locale, char[] inputText, float[] widths,
+ int length, float firstWidth, int firstWidthLineCount, float restWidth,
+ int[] variableTabStops, int defaultTabStop, boolean optimize, LineBreaks recycle,
+ int[] recycleBreaks, float[] recycleWidths, boolean[] recycleFlags, int recycleLength) {
+
+ // compute all possible breakpoints.
+ BreakIterator it = BreakIterator.getLineInstance(new ULocale(locale));
+ it.setText(new Segment(inputText, 0, length));
+ // average word length in english is 5. So, initialize the possible breaks with a guess.
+ List<Integer> breaks = new ArrayList<Integer>((int) Math.ceil(length / 5d));
+ int loc;
+ it.first();
+ while ((loc = it.next()) != BreakIterator.DONE) {
+ breaks.add(loc);
}
- int breakOpp = iterator.first();
- recycle[0] = breakOpp;
- //noinspection ConstantConditions
- assert BreakIterator.DONE == -1;
- for (int i = 1; breakOpp != BreakIterator.DONE; ++i) {
- if (i >= recycle.length) {
- recycle = doubleSize(recycle);
- }
- assert (i < recycle.length);
- breakOpp = iterator.next();
- recycle[i] = breakOpp;
+
+ LineWidth lineWidth = new LineWidth(firstWidth, firstWidthLineCount, restWidth);
+ TabStops tabStopCalculator = new TabStops(variableTabStops, defaultTabStop);
+ List<Primitive> primitives = computePrimitives(inputText, widths, length, breaks);
+ LineBreaker lineBreaker;
+ if (optimize) {
+ lineBreaker = new OptimizingLineBreaker(primitives, lineWidth, tabStopCalculator);
+ } else {
+ lineBreaker = new GreedyLineBreaker(primitives, lineWidth, tabStopCalculator);
}
- return recycle;
+ lineBreaker.computeBreaks(recycle);
+ return recycle.breaks.length;
}
- private static int[] doubleSize(int[] array) {
- return Arrays.copyOf(array, array.length * 2);
+ /**
+ * Compute metadata each character - things which help in deciding if it's possible to break
+ * at a point or not.
+ */
+ @NonNull
+ private static List<Primitive> computePrimitives(@NonNull char[] text, @NonNull float[] widths,
+ int length, @NonNull List<Integer> breaks) {
+ // Initialize the list with a guess of the number of primitives:
+ // 2 Primitives per non-whitespace char and approx 5 chars per word (i.e. 83% chars)
+ List<Primitive> primitives = new ArrayList<Primitive>(((int) Math.ceil(length * 1.833)));
+ int breaksSize = breaks.size();
+ int breakIndex = 0;
+ for (int i = 0; i < length; i++) {
+ char c = text[i];
+ if (c == CHAR_SPACE || c == CHAR_ZWSP) {
+ primitives.add(PrimitiveType.GLUE.getNewPrimitive(i, widths[i]));
+ } else if (c == CHAR_TAB) {
+ primitives.add(PrimitiveType.VARIABLE.getNewPrimitive(i));
+ } else if (c != CHAR_NEWLINE) {
+ while (breakIndex < breaksSize && breaks.get(breakIndex) < i) {
+ breakIndex++;
+ }
+ Primitive p;
+ if (widths[i] != 0) {
+ if (breakIndex < breaksSize && breaks.get(breakIndex) == i) {
+ p = PrimitiveType.PENALTY.getNewPrimitive(i, 0, 0);
+ } else {
+ p = PrimitiveType.WORD_BREAK.getNewPrimitive(i, 0);
+ }
+ primitives.add(p);
+ }
+
+ primitives.add(PrimitiveType.BOX.getNewPrimitive(i, widths[i]));
+ }
+ }
+ // final break at end of everything
+ primitives.add(
+ PrimitiveType.PENALTY.getNewPrimitive(length, 0, -PrimitiveType.PENALTY_INFINITY));
+ return primitives;
}
}
diff --git a/tools/layoutlib/bridge/src/android/text/TabStops.java b/tools/layoutlib/bridge/src/android/text/TabStops.java
new file mode 100644
index 0000000..cff6b93
--- /dev/null
+++ b/tools/layoutlib/bridge/src/android/text/TabStops.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.text;
+
+import com.android.annotations.Nullable;
+
+// Based on the native implementation of TabStops in
+// frameworks/base/core/jni/android_text_StaticLayout.cpp revision b808260
+public class TabStops {
+ @Nullable
+ private int[] mStops;
+ private final int mTabWidth;
+
+ public TabStops(@Nullable int[] stops, int defaultTabWidth) {
+ mTabWidth = defaultTabWidth;
+ mStops = stops;
+ }
+
+ public float width(float widthSoFar) {
+ if (mStops != null) {
+ for (int i : mStops) {
+ if (i > widthSoFar) {
+ return i;
+ }
+ }
+ }
+ // find the next tabStop after widthSoFar.
+ return (int) ((widthSoFar + mTabWidth) / mTabWidth) * mTabWidth;
+ }
+}
diff --git a/tools/layoutlib/bridge/src/android/util/FloatMath_Delegate.java b/tools/layoutlib/bridge/src/android/util/FloatMath_Delegate.java
deleted file mode 100644
index 8b4c60b..0000000
--- a/tools/layoutlib/bridge/src/android/util/FloatMath_Delegate.java
+++ /dev/null
@@ -1,132 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.util;
-
-import com.android.layoutlib.bridge.impl.DelegateManager;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-/**
- * Delegate implementing the native methods of android.util.FloatMath
- *
- * Through the layoutlib_create tool, the original native methods of FloatMath have been replaced
- * by calls to methods of the same name in this delegate class.
- *
- * Because it's a stateless class to start with, there's no need to keep a {@link DelegateManager}
- * around to map int to instance of the delegate.
- *
- */
-/*package*/ final class FloatMath_Delegate {
-
- /** Prevents instantiation. */
- private FloatMath_Delegate() {}
-
- /**
- * Returns the float conversion of the most positive (i.e. closest to
- * positive infinity) integer value which is less than the argument.
- *
- * @param value to be converted
- * @return the floor of value
- */
- @LayoutlibDelegate
- /*package*/ static float floor(float value) {
- return (float)Math.floor(value);
- }
-
- /**
- * Returns the float conversion of the most negative (i.e. closest to
- * negative infinity) integer value which is greater than the argument.
- *
- * @param value to be converted
- * @return the ceiling of value
- */
- @LayoutlibDelegate
- /*package*/ static float ceil(float value) {
- return (float)Math.ceil(value);
- }
-
- /**
- * Returns the closest float approximation of the sine of the argument.
- *
- * @param angle to compute the cosine of, in radians
- * @return the sine of angle
- */
- @LayoutlibDelegate
- /*package*/ static float sin(float angle) {
- return (float)Math.sin(angle);
- }
-
- /**
- * Returns the closest float approximation of the cosine of the argument.
- *
- * @param angle to compute the cosine of, in radians
- * @return the cosine of angle
- */
- @LayoutlibDelegate
- /*package*/ static float cos(float angle) {
- return (float)Math.cos(angle);
- }
-
- /**
- * Returns the closest float approximation of the square root of the
- * argument.
- *
- * @param value to compute sqrt of
- * @return the square root of value
- */
- @LayoutlibDelegate
- /*package*/ static float sqrt(float value) {
- return (float)Math.sqrt(value);
- }
-
- /**
- * Returns the closest float approximation of the raising "e" to the power
- * of the argument.
- *
- * @param value to compute the exponential of
- * @return the exponential of value
- */
- @LayoutlibDelegate
- /*package*/ static float exp(float value) {
- return (float)Math.exp(value);
- }
-
- /**
- * Returns the closest float approximation of the result of raising {@code
- * x} to the power of {@code y}.
- *
- * @param x the base of the operation.
- * @param y the exponent of the operation.
- * @return {@code x} to the power of {@code y}.
- */
- @LayoutlibDelegate
- /*package*/ static float pow(float x, float y) {
- return (float)Math.pow(x, y);
- }
-
- /**
- * Returns {@code sqrt(}<i>{@code x}</i><sup>{@code 2}</sup>{@code +} <i>
- * {@code y}</i><sup>{@code 2}</sup>{@code )}.
- *
- * @param x a float number
- * @param y a float number
- * @return the hypotenuse
- */
- @LayoutlibDelegate
- /*package*/ static float hypot(float x, float y) {
- return (float)Math.sqrt(x*x + y*y);
- }
-}
diff --git a/tools/layoutlib/bridge/src/android/view/RenderNode_Delegate.java b/tools/layoutlib/bridge/src/android/view/RenderNode_Delegate.java
new file mode 100644
index 0000000..6c949d9
--- /dev/null
+++ b/tools/layoutlib/bridge/src/android/view/RenderNode_Delegate.java
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.view;
+
+import com.android.layoutlib.bridge.impl.DelegateManager;
+import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
+
+/**
+ * Delegate implementing the native methods of {@link RenderNode}
+ * <p/>
+ * Through the layoutlib_create tool, some native methods of RenderNode have been replaced by calls
+ * to methods of the same name in this delegate class.
+ *
+ * @see DelegateManager
+ */
+public class RenderNode_Delegate {
+
+
+ // ---- delegate manager ----
+ private static final DelegateManager<RenderNode_Delegate> sManager =
+ new DelegateManager<RenderNode_Delegate>(RenderNode_Delegate.class);
+
+
+ private float mLift;
+ @SuppressWarnings("UnusedDeclaration")
+ private String mName;
+
+ @LayoutlibDelegate
+ /*package*/ static long nCreate(String name) {
+ RenderNode_Delegate renderNodeDelegate = new RenderNode_Delegate();
+ renderNodeDelegate.mName = name;
+ return sManager.addNewDelegate(renderNodeDelegate);
+ }
+
+ @LayoutlibDelegate
+ /*package*/ static void nDestroyRenderNode(long renderNode) {
+ sManager.removeJavaReferenceFor(renderNode);
+ }
+
+ @LayoutlibDelegate
+ /*package*/ static boolean nSetElevation(long renderNode, float lift) {
+ RenderNode_Delegate delegate = sManager.getDelegate(renderNode);
+ if (delegate != null && delegate.mLift != lift) {
+ delegate.mLift = lift;
+ return true;
+ }
+ return false;
+ }
+
+ @LayoutlibDelegate
+ /*package*/ static float nGetElevation(long renderNode) {
+ RenderNode_Delegate delegate = sManager.getDelegate(renderNode);
+ if (delegate != null) {
+ return delegate.mLift;
+ }
+ return 0f;
+ }
+}
diff --git a/tools/layoutlib/bridge/src/android/view/ShadowPainter.java b/tools/layoutlib/bridge/src/android/view/ShadowPainter.java
new file mode 100644
index 0000000..38846bd
--- /dev/null
+++ b/tools/layoutlib/bridge/src/android/view/ShadowPainter.java
@@ -0,0 +1,415 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.view;
+
+import com.android.annotations.NonNull;
+
+import java.awt.Graphics2D;
+import java.awt.Image;
+import java.awt.image.BufferedImage;
+import java.awt.image.DataBufferInt;
+import java.io.IOException;
+import java.io.InputStream;
+
+import javax.imageio.ImageIO;
+
+public class ShadowPainter {
+
+ /**
+ * Adds a drop shadow to a semi-transparent image (of an arbitrary shape) and returns it as a
+ * new image. This method attempts to mimic the same visual characteristics as the rectangular
+ * shadow painting methods in this class, {@link #createRectangularDropShadow(java.awt.image.BufferedImage)}
+ * and {@link #createSmallRectangularDropShadow(java.awt.image.BufferedImage)}.
+ *
+ * @param source the source image
+ * @param shadowSize the size of the shadow, normally {@link #SHADOW_SIZE or {@link
+ * #SMALL_SHADOW_SIZE}}
+ *
+ * @return a new image with the shadow painted in
+ */
+ @NonNull
+ public static BufferedImage createDropShadow(BufferedImage source, int shadowSize) {
+ shadowSize /= 2; // make shadow size have the same meaning as in the other shadow paint methods in this class
+
+ return createDropShadow(source, shadowSize, 0.7f, 0);
+ }
+
+ /**
+ * Creates a drop shadow of a given image and returns a new image which shows the input image on
+ * top of its drop shadow.
+ * <p/>
+ * <b>NOTE: If the shape is rectangular and opaque, consider using {@link
+ * #drawRectangleShadow(Graphics2D, int, int, int, int)} instead.</b>
+ *
+ * @param source the source image to be shadowed
+ * @param shadowSize the size of the shadow in pixels
+ * @param shadowOpacity the opacity of the shadow, with 0=transparent and 1=opaque
+ * @param shadowRgb the RGB int to use for the shadow color
+ *
+ * @return a new image with the source image on top of its shadow
+ */
+ @SuppressWarnings({"SuspiciousNameCombination", "UnnecessaryLocalVariable"}) // Imported code
+ public static BufferedImage createDropShadow(BufferedImage source, int shadowSize,
+ float shadowOpacity, int shadowRgb) {
+
+ // This code is based on
+ // http://www.jroller.com/gfx/entry/non_rectangular_shadow
+
+ BufferedImage image;
+ int width = source.getWidth();
+ int height = source.getHeight();
+ image = new BufferedImage(width + SHADOW_SIZE, height + SHADOW_SIZE,
+ BufferedImage.TYPE_INT_ARGB);
+
+ Graphics2D g2 = image.createGraphics();
+ g2.drawImage(image, shadowSize, shadowSize, null);
+
+ int dstWidth = image.getWidth();
+ int dstHeight = image.getHeight();
+
+ int left = (shadowSize - 1) >> 1;
+ int right = shadowSize - left;
+ int xStart = left;
+ int xStop = dstWidth - right;
+ int yStart = left;
+ int yStop = dstHeight - right;
+
+ shadowRgb &= 0x00FFFFFF;
+
+ int[] aHistory = new int[shadowSize];
+ int historyIdx;
+
+ int aSum;
+
+ int[] dataBuffer = ((DataBufferInt) image.getRaster().getDataBuffer()).getData();
+ int lastPixelOffset = right * dstWidth;
+ float sumDivider = shadowOpacity / shadowSize;
+
+ // horizontal pass
+ for (int y = 0, bufferOffset = 0; y < dstHeight; y++, bufferOffset = y * dstWidth) {
+ aSum = 0;
+ historyIdx = 0;
+ for (int x = 0; x < shadowSize; x++, bufferOffset++) {
+ int a = dataBuffer[bufferOffset] >>> 24;
+ aHistory[x] = a;
+ aSum += a;
+ }
+
+ bufferOffset -= right;
+
+ for (int x = xStart; x < xStop; x++, bufferOffset++) {
+ int a = (int) (aSum * sumDivider);
+ dataBuffer[bufferOffset] = a << 24 | shadowRgb;
+
+ // subtract the oldest pixel from the sum
+ aSum -= aHistory[historyIdx];
+
+ // get the latest pixel
+ a = dataBuffer[bufferOffset + right] >>> 24;
+ aHistory[historyIdx] = a;
+ aSum += a;
+
+ if (++historyIdx >= shadowSize) {
+ historyIdx -= shadowSize;
+ }
+ }
+ }
+ // vertical pass
+ for (int x = 0, bufferOffset = 0; x < dstWidth; x++, bufferOffset = x) {
+ aSum = 0;
+ historyIdx = 0;
+ for (int y = 0; y < shadowSize; y++, bufferOffset += dstWidth) {
+ int a = dataBuffer[bufferOffset] >>> 24;
+ aHistory[y] = a;
+ aSum += a;
+ }
+
+ bufferOffset -= lastPixelOffset;
+
+ for (int y = yStart; y < yStop; y++, bufferOffset += dstWidth) {
+ int a = (int) (aSum * sumDivider);
+ dataBuffer[bufferOffset] = a << 24 | shadowRgb;
+
+ // subtract the oldest pixel from the sum
+ aSum -= aHistory[historyIdx];
+
+ // get the latest pixel
+ a = dataBuffer[bufferOffset + lastPixelOffset] >>> 24;
+ aHistory[historyIdx] = a;
+ aSum += a;
+
+ if (++historyIdx >= shadowSize) {
+ historyIdx -= shadowSize;
+ }
+ }
+ }
+
+ g2.drawImage(source, null, 0, 0);
+ g2.dispose();
+
+ return image;
+ }
+
+ /**
+ * Draws a rectangular drop shadow (of size {@link #SHADOW_SIZE} by {@link #SHADOW_SIZE} around
+ * the given source and returns a new image with both combined
+ *
+ * @param source the source image
+ *
+ * @return the source image with a drop shadow on the bottom and right
+ */
+ @SuppressWarnings("UnusedDeclaration")
+ public static BufferedImage createRectangularDropShadow(BufferedImage source) {
+ int type = source.getType();
+ if (type == BufferedImage.TYPE_CUSTOM) {
+ type = BufferedImage.TYPE_INT_ARGB;
+ }
+
+ int width = source.getWidth();
+ int height = source.getHeight();
+ BufferedImage image;
+ image = new BufferedImage(width + SHADOW_SIZE, height + SHADOW_SIZE, type);
+ Graphics2D g = image.createGraphics();
+ g.drawImage(source, 0, 0, null);
+ drawRectangleShadow(image, 0, 0, width, height);
+ g.dispose();
+
+ return image;
+ }
+
+ /**
+ * Draws a small rectangular drop shadow (of size {@link #SMALL_SHADOW_SIZE} by {@link
+ * #SMALL_SHADOW_SIZE} around the given source and returns a new image with both combined
+ *
+ * @param source the source image
+ *
+ * @return the source image with a drop shadow on the bottom and right
+ */
+ @SuppressWarnings("UnusedDeclaration")
+ public static BufferedImage createSmallRectangularDropShadow(BufferedImage source) {
+ int type = source.getType();
+ if (type == BufferedImage.TYPE_CUSTOM) {
+ type = BufferedImage.TYPE_INT_ARGB;
+ }
+
+ int width = source.getWidth();
+ int height = source.getHeight();
+
+ BufferedImage image;
+ image = new BufferedImage(width + SMALL_SHADOW_SIZE, height + SMALL_SHADOW_SIZE, type);
+
+ Graphics2D g = image.createGraphics();
+ g.drawImage(source, 0, 0, null);
+ drawSmallRectangleShadow(image, 0, 0, width, height);
+ g.dispose();
+
+ return image;
+ }
+
+ /**
+ * Draws a drop shadow for the given rectangle into the given context. It will not draw anything
+ * if the rectangle is smaller than a minimum determined by the assets used to draw the shadow
+ * graphics. The size of the shadow is {@link #SHADOW_SIZE}.
+ *
+ * @param image the image to draw the shadow into
+ * @param x the left coordinate of the left hand side of the rectangle
+ * @param y the top coordinate of the top of the rectangle
+ * @param width the width of the rectangle
+ * @param height the height of the rectangle
+ */
+ public static void drawRectangleShadow(BufferedImage image,
+ int x, int y, int width, int height) {
+ Graphics2D gc = image.createGraphics();
+ try {
+ drawRectangleShadow(gc, x, y, width, height);
+ } finally {
+ gc.dispose();
+ }
+ }
+
+ /**
+ * Draws a small drop shadow for the given rectangle into the given context. It will not draw
+ * anything if the rectangle is smaller than a minimum determined by the assets used to draw the
+ * shadow graphics. The size of the shadow is {@link #SMALL_SHADOW_SIZE}.
+ *
+ * @param image the image to draw the shadow into
+ * @param x the left coordinate of the left hand side of the rectangle
+ * @param y the top coordinate of the top of the rectangle
+ * @param width the width of the rectangle
+ * @param height the height of the rectangle
+ */
+ public static void drawSmallRectangleShadow(BufferedImage image,
+ int x, int y, int width, int height) {
+ Graphics2D gc = image.createGraphics();
+ try {
+ drawSmallRectangleShadow(gc, x, y, width, height);
+ } finally {
+ gc.dispose();
+ }
+ }
+
+ /**
+ * The width and height of the drop shadow painted by
+ * {@link #drawRectangleShadow(Graphics2D, int, int, int, int)}
+ */
+ public static final int SHADOW_SIZE = 20; // DO NOT EDIT. This corresponds to bitmap graphics
+
+ /**
+ * The width and height of the drop shadow painted by
+ * {@link #drawSmallRectangleShadow(Graphics2D, int, int, int, int)}
+ */
+ public static final int SMALL_SHADOW_SIZE = 10; // DO NOT EDIT. Corresponds to bitmap graphics
+
+ /**
+ * Draws a drop shadow for the given rectangle into the given context. It will not draw anything
+ * if the rectangle is smaller than a minimum determined by the assets used to draw the shadow
+ * graphics.
+ *
+ * @param gc the graphics context to draw into
+ * @param x the left coordinate of the left hand side of the rectangle
+ * @param y the top coordinate of the top of the rectangle
+ * @param width the width of the rectangle
+ * @param height the height of the rectangle
+ */
+ public static void drawRectangleShadow(Graphics2D gc, int x, int y, int width, int height) {
+ assert ShadowBottomLeft != null;
+ assert ShadowBottomRight.getWidth(null) == SHADOW_SIZE;
+ assert ShadowBottomRight.getHeight(null) == SHADOW_SIZE;
+
+ int blWidth = ShadowBottomLeft.getWidth(null);
+ int trHeight = ShadowTopRight.getHeight(null);
+ if (width < blWidth) {
+ return;
+ }
+ if (height < trHeight) {
+ return;
+ }
+
+ gc.drawImage(ShadowBottomLeft, x - ShadowBottomLeft.getWidth(null), y + height, null);
+ gc.drawImage(ShadowBottomRight, x + width, y + height, null);
+ gc.drawImage(ShadowTopRight, x + width, y, null);
+ gc.drawImage(ShadowTopLeft, x - ShadowTopLeft.getWidth(null), y, null);
+ gc.drawImage(ShadowBottom,
+ x, y + height, x + width, y + height + ShadowBottom.getHeight(null),
+ 0, 0, ShadowBottom.getWidth(null), ShadowBottom.getHeight(null), null);
+ gc.drawImage(ShadowRight,
+ x + width, y + ShadowTopRight.getHeight(null), x + width + ShadowRight.getWidth(null), y + height,
+ 0, 0, ShadowRight.getWidth(null), ShadowRight.getHeight(null), null);
+ gc.drawImage(ShadowLeft,
+ x - ShadowLeft.getWidth(null), y + ShadowTopLeft.getHeight(null), x, y + height,
+ 0, 0, ShadowLeft.getWidth(null), ShadowLeft.getHeight(null), null);
+ }
+
+ /**
+ * Draws a small drop shadow for the given rectangle into the given context. It will not draw
+ * anything if the rectangle is smaller than a minimum determined by the assets used to draw the
+ * shadow graphics.
+ * <p/>
+ *
+ * @param gc the graphics context to draw into
+ * @param x the left coordinate of the left hand side of the rectangle
+ * @param y the top coordinate of the top of the rectangle
+ * @param width the width of the rectangle
+ * @param height the height of the rectangle
+ */
+ public static void drawSmallRectangleShadow(Graphics2D gc, int x, int y, int width,
+ int height) {
+ assert Shadow2BottomLeft != null;
+ assert Shadow2TopRight != null;
+ assert Shadow2BottomRight.getWidth(null) == SMALL_SHADOW_SIZE;
+ assert Shadow2BottomRight.getHeight(null) == SMALL_SHADOW_SIZE;
+
+ int blWidth = Shadow2BottomLeft.getWidth(null);
+ int trHeight = Shadow2TopRight.getHeight(null);
+ if (width < blWidth) {
+ return;
+ }
+ if (height < trHeight) {
+ return;
+ }
+
+ gc.drawImage(Shadow2BottomLeft, x - Shadow2BottomLeft.getWidth(null), y + height, null);
+ gc.drawImage(Shadow2BottomRight, x + width, y + height, null);
+ gc.drawImage(Shadow2TopRight, x + width, y, null);
+ gc.drawImage(Shadow2TopLeft, x - Shadow2TopLeft.getWidth(null), y, null);
+ gc.drawImage(Shadow2Bottom,
+ x, y + height, x + width, y + height + Shadow2Bottom.getHeight(null),
+ 0, 0, Shadow2Bottom.getWidth(null), Shadow2Bottom.getHeight(null), null);
+ gc.drawImage(Shadow2Right,
+ x + width, y + Shadow2TopRight.getHeight(null), x + width + Shadow2Right.getWidth(null), y + height,
+ 0, 0, Shadow2Right.getWidth(null), Shadow2Right.getHeight(null), null);
+ gc.drawImage(Shadow2Left,
+ x - Shadow2Left.getWidth(null), y + Shadow2TopLeft.getHeight(null), x, y + height,
+ 0, 0, Shadow2Left.getWidth(null), Shadow2Left.getHeight(null), null);
+ }
+
+ private static Image loadIcon(String name) {
+ InputStream inputStream = ShadowPainter.class.getResourceAsStream(name);
+ if (inputStream == null) {
+ throw new RuntimeException("Unable to load image for shadow: " + name);
+ }
+ try {
+ return ImageIO.read(inputStream);
+ } catch (IOException e) {
+ throw new RuntimeException("Unable to load image for shadow:" + name, e);
+ } finally {
+ try {
+ inputStream.close();
+ } catch (IOException e) {
+ // ignore.
+ }
+ }
+ }
+
+ // Shadow graphics. This was generated by creating a drop shadow in
+ // Gimp, using the parameters x offset=10, y offset=10, blur radius=10,
+ // (for the small drop shadows x offset=10, y offset=10, blur radius=10)
+ // color=black, and opacity=51. These values attempt to make a shadow
+ // that is legible both for dark and light themes, on top of the
+ // canvas background (rgb(150,150,150). Darker shadows would tend to
+ // blend into the foreground for a dark holo screen, and lighter shadows
+ // would be hard to spot on the canvas background. If you make adjustments,
+ // make sure to check the shadow with both dark and light themes.
+ //
+ // After making the graphics, I cut out the top right, bottom left
+ // and bottom right corners as 20x20 images, and these are reproduced by
+ // painting them in the corresponding places in the target graphics context.
+ // I then grabbed a single horizontal gradient line from the middle of the
+ // right edge,and a single vertical gradient line from the bottom. These
+ // are then painted scaled/stretched in the target to fill the gaps between
+ // the three corner images.
+ //
+ // Filenames: bl=bottom left, b=bottom, br=bottom right, r=right, tr=top right
+
+ // Normal Drop Shadow
+ private static final Image ShadowBottom = loadIcon("/icons/shadow-b.png");
+ private static final Image ShadowBottomLeft = loadIcon("/icons/shadow-bl.png");
+ private static final Image ShadowBottomRight = loadIcon("/icons/shadow-br.png");
+ private static final Image ShadowRight = loadIcon("/icons/shadow-r.png");
+ private static final Image ShadowTopRight = loadIcon("/icons/shadow-tr.png");
+ private static final Image ShadowTopLeft = loadIcon("/icons/shadow-tl.png");
+ private static final Image ShadowLeft = loadIcon("/icons/shadow-l.png");
+
+ // Small Drop Shadow
+ private static final Image Shadow2Bottom = loadIcon("/icons/shadow2-b.png");
+ private static final Image Shadow2BottomLeft = loadIcon("/icons/shadow2-bl.png");
+ private static final Image Shadow2BottomRight = loadIcon("/icons/shadow2-br.png");
+ private static final Image Shadow2Right = loadIcon("/icons/shadow2-r.png");
+ private static final Image Shadow2TopRight = loadIcon("/icons/shadow2-tr.png");
+ private static final Image Shadow2TopLeft = loadIcon("/icons/shadow2-tl.png");
+ private static final Image Shadow2Left = loadIcon("/icons/shadow2-l.png");
+}
diff --git a/tools/layoutlib/bridge/src/android/view/ViewGroup_Delegate.java b/tools/layoutlib/bridge/src/android/view/ViewGroup_Delegate.java
new file mode 100644
index 0000000..a6c00f7
--- /dev/null
+++ b/tools/layoutlib/bridge/src/android/view/ViewGroup_Delegate.java
@@ -0,0 +1,205 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.view;
+
+import com.android.annotations.NonNull;
+import com.android.layoutlib.bridge.android.BridgeContext;
+import com.android.resources.Density;
+import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
+
+import android.content.Context;
+import android.graphics.Bitmap;
+import android.graphics.Bitmap_Delegate;
+import android.graphics.Canvas;
+import android.graphics.Outline;
+import android.graphics.Path_Delegate;
+import android.graphics.Rect;
+import android.graphics.Region.Op;
+import android.util.DisplayMetrics;
+import android.util.TypedValue;
+import android.view.animation.Transformation;
+
+import java.awt.Graphics2D;
+import java.awt.image.BufferedImage;
+
+/**
+ * Delegate used to provide new implementation of a select few methods of {@link ViewGroup}
+ * <p/>
+ * Through the layoutlib_create tool, the original methods of ViewGroup have been replaced by calls
+ * to methods of the same name in this delegate class.
+ */
+public class ViewGroup_Delegate {
+
+ /**
+ * Overrides the original drawChild call in ViewGroup to draw the shadow.
+ */
+ @LayoutlibDelegate
+ /*package*/ static boolean drawChild(ViewGroup thisVG, Canvas canvas, View child,
+ long drawingTime) {
+ boolean retVal = thisVG.drawChild_Original(canvas, child, drawingTime);
+ if (child.getZ() > thisVG.getZ()) {
+ ViewOutlineProvider outlineProvider = child.getOutlineProvider();
+ Outline outline = new Outline();
+ outlineProvider.getOutline(child, outline);
+
+ if (outline.mPath != null || (outline.mRect != null && !outline.mRect.isEmpty())) {
+ int restoreTo = transformCanvas(thisVG, canvas, child);
+ drawShadow(thisVG, canvas, child, outline);
+ canvas.restoreToCount(restoreTo);
+ }
+ }
+ return retVal;
+ }
+
+ private static void drawShadow(ViewGroup parent, Canvas canvas, View child,
+ Outline outline) {
+ BufferedImage shadow = null;
+ int x = 0;
+ if (outline.mRect != null) {
+ Shadow s = getRectShadow(parent, canvas, child, outline);
+ shadow = s.mShadow;
+ x = -s.mShadowWidth;
+ } else if (outline.mPath != null) {
+ shadow = getPathShadow(child, outline, canvas);
+ }
+ if (shadow == null) {
+ return;
+ }
+ Bitmap bitmap = Bitmap_Delegate.createBitmap(shadow, false,
+ Density.getEnum(canvas.getDensity()));
+ Rect clipBounds = canvas.getClipBounds();
+ Rect newBounds = new Rect(clipBounds);
+ newBounds.left = newBounds.left + x;
+ canvas.clipRect(newBounds, Op.REPLACE);
+ canvas.drawBitmap(bitmap, x, 0, null);
+ canvas.clipRect(clipBounds, Op.REPLACE);
+ }
+
+ private static Shadow getRectShadow(ViewGroup parent, Canvas canvas, View child,
+ Outline outline) {
+ BufferedImage shadow;
+ Rect clipBounds = canvas.getClipBounds();
+ if (clipBounds.isEmpty()) {
+ return null;
+ }
+ float height = child.getZ() - parent.getZ();
+ // Draw large shadow if difference in z index is more than 10dp
+ float largeShadowThreshold = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 10f,
+ getMetrics(child));
+ boolean largeShadow = height > largeShadowThreshold;
+ int shadowSize = largeShadow ? ShadowPainter.SHADOW_SIZE : ShadowPainter.SMALL_SHADOW_SIZE;
+ shadow = new BufferedImage(clipBounds.width() + shadowSize, clipBounds.height(),
+ BufferedImage.TYPE_INT_ARGB);
+ Graphics2D graphics = shadow.createGraphics();
+ Rect rect = outline.mRect;
+ if (largeShadow) {
+ ShadowPainter.drawRectangleShadow(graphics,
+ rect.left + shadowSize, rect.top, rect.width(), rect.height());
+ } else {
+ ShadowPainter.drawSmallRectangleShadow(graphics,
+ rect.left + shadowSize, rect.top, rect.width(), rect.height());
+ }
+ graphics.dispose();
+ return new Shadow(shadow, shadowSize);
+ }
+
+ @NonNull
+ private static DisplayMetrics getMetrics(View view) {
+ Context context = view.getContext();
+ while (context instanceof ContextThemeWrapper) {
+ context = ((ContextThemeWrapper) context).getBaseContext();
+ }
+ if (context instanceof BridgeContext) {
+ return ((BridgeContext) context).getMetrics();
+ }
+ throw new RuntimeException("View " + view.getClass().getName() + " not created with the " +
+ "right context");
+ }
+
+ private static BufferedImage getPathShadow(View child, Outline outline, Canvas canvas) {
+ Rect clipBounds = canvas.getClipBounds();
+ BufferedImage image = new BufferedImage(clipBounds.width(), clipBounds.height(),
+ BufferedImage.TYPE_INT_ARGB);
+ Graphics2D graphics = image.createGraphics();
+ graphics.draw(Path_Delegate.getDelegate(outline.mPath.mNativePath).getJavaShape());
+ graphics.dispose();
+ return ShadowPainter.createDropShadow(image, ((int) child.getZ()));
+ }
+
+ // Copied from android.view.View#draw(Canvas, ViewGroup, long) and removed code paths
+ // which were never taken. Ideally, we should hook up the shadow code in the same method so
+ // that we don't have to transform the canvas twice.
+ private static int transformCanvas(ViewGroup thisVG, Canvas canvas, View child) {
+ final int restoreTo = canvas.save();
+ final boolean childHasIdentityMatrix = child.hasIdentityMatrix();
+ int flags = thisVG.mGroupFlags;
+ Transformation transformToApply = null;
+ boolean concatMatrix = false;
+ if ((flags & ViewGroup.FLAG_SUPPORT_STATIC_TRANSFORMATIONS) != 0) {
+ final Transformation t = thisVG.getChildTransformation();
+ final boolean hasTransform = thisVG.getChildStaticTransformation(child, t);
+ if (hasTransform) {
+ final int transformType = t.getTransformationType();
+ transformToApply = transformType != Transformation.TYPE_IDENTITY ? t : null;
+ concatMatrix = (transformType & Transformation.TYPE_MATRIX) != 0;
+ }
+ }
+ concatMatrix |= childHasIdentityMatrix;
+
+ child.computeScroll();
+ int sx = child.mScrollX;
+ int sy = child.mScrollY;
+
+ canvas.translate(child.mLeft - sx, child.mTop - sy);
+ float alpha = child.getAlpha() * child.getTransitionAlpha();
+
+ if (transformToApply != null || alpha < 1 || !childHasIdentityMatrix) {
+ if (transformToApply != null || !childHasIdentityMatrix) {
+ int transX = -sx;
+ int transY = -sy;
+
+ if (transformToApply != null) {
+ if (concatMatrix) {
+ // Undo the scroll translation, apply the transformation matrix,
+ // then redo the scroll translate to get the correct result.
+ canvas.translate(-transX, -transY);
+ canvas.concat(transformToApply.getMatrix());
+ canvas.translate(transX, transY);
+ }
+ if (!childHasIdentityMatrix) {
+ canvas.translate(-transX, -transY);
+ canvas.concat(child.getMatrix());
+ canvas.translate(transX, transY);
+ }
+ }
+
+ }
+ }
+ return restoreTo;
+ }
+
+ private static class Shadow {
+ public BufferedImage mShadow;
+ public int mShadowWidth;
+
+ public Shadow(BufferedImage shadow, int shadowWidth) {
+ mShadow = shadow;
+ mShadowWidth = shadowWidth;
+ }
+
+ }
+}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeRenderSession.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeRenderSession.java
index e0f87fd..feb2590 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeRenderSession.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeRenderSession.java
@@ -86,11 +86,14 @@
}
@Override
- public Result render(long timeout) {
+ public Result render(long timeout, boolean forceMeasure) {
try {
Bridge.prepareThread();
mLastResult = mSession.acquire(timeout);
if (mLastResult.isSuccess()) {
+ if (forceMeasure) {
+ mSession.invalidateRenderingSize();
+ }
mLastResult = mSession.render(false /*freshRender*/);
}
} finally {
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java
index 3d3afa4..aeb70e9 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java
@@ -479,6 +479,23 @@
StyleResourceValue style = getStyleByDynamicId(resid);
if (style == null) {
+ // In some cases, style may not be a dynamic id, so we do a full search.
+ ResourceReference ref = resolveId(resid);
+ if (ref != null) {
+ if (ref.isFramework()) {
+ ref =
+ getRenderResources().getFrameworkResource(ResourceType.STYLE, ref.getName());
+ } else {
+ ref =
+ getRenderResources().getProjectResource(ResourceType.STYLE, ref.getName());
+ }
+ if (ref instanceof StyleResourceValue) {
+ style = ((StyleResourceValue) ref);
+ }
+ }
+ }
+
+ if (style == null) {
throw new Resources.NotFoundException();
}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgePowerManager.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgePowerManager.java
index 05a6fd6..39ebdfc 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgePowerManager.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgePowerManager.java
@@ -116,11 +116,6 @@
}
@Override
- public void setMaximumScreenOffTimeoutFromDeviceAdmin(int arg0) throws RemoteException {
- // pass for now.
- }
-
- @Override
public void setStayOnSetting(int arg0) throws RemoteException {
// pass for now.
}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/ActionBarLayout.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/ActionBarLayout.java
index 57fd68e..2ff8d37 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/ActionBarLayout.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/ActionBarLayout.java
@@ -18,6 +18,7 @@
import com.android.annotations.NonNull;
import com.android.annotations.Nullable;
+import com.android.ide.common.rendering.api.RenderResources;
import com.android.ide.common.rendering.api.ResourceValue;
import com.android.ide.common.rendering.api.SessionParams;
import com.android.internal.R;
@@ -37,7 +38,6 @@
import android.view.ViewGroup.LayoutParams;
import android.widget.ActionMenuPresenter;
import android.widget.FrameLayout;
-import android.widget.LinearLayout;
import android.widget.ListAdapter;
import android.widget.ListView;
import android.widget.RelativeLayout;
@@ -49,15 +49,23 @@
private static final String LAYOUT_ATTR_NAME = "windowActionBarFullscreenDecorLayout";
// The Action Bar
- @NonNull private CustomActionBarWrapper mActionBar;
+ @NonNull
+ private CustomActionBarWrapper mActionBar;
// Store another reference to the context so that we don't have to cast it repeatedly.
- @NonNull private final BridgeContext mBridgeContext;
+ @NonNull
+ private final BridgeContext mBridgeContext;
- @NonNull private FrameLayout mContentRoot;
+ @NonNull
+ private FrameLayout mContentRoot;
// A fake parent for measuring views.
- @Nullable private ViewGroup mMeasureParent;
+ @Nullable
+ private ViewGroup mMeasureParent;
+
+ // A Layout that contains the inflated action bar. The menu popup is added to this layout.
+ @NonNull
+ private final RelativeLayout mEnclosingLayout;
/**
* Inflate the action bar and attach it to {@code parentView}
@@ -90,20 +98,25 @@
if (layoutId == 0) {
throw new RuntimeException(error);
}
+ // Create a RelativeLayout to hold the action bar. The layout is needed so that we may
+ // add the menu popup to it.
+ mEnclosingLayout = new RelativeLayout(mBridgeContext);
+ setMatchParent(mEnclosingLayout);
+ parentView.addView(mEnclosingLayout);
+
// Inflate action bar layout.
- View decorContent = LayoutInflater.from(context).inflate(layoutId, parentView, true);
+ View decorContent = LayoutInflater.from(context).inflate(layoutId, mEnclosingLayout, true);
mActionBar = CustomActionBarWrapper.getActionBarWrapper(context, params, decorContent);
- FrameLayout contentRoot = (FrameLayout) parentView.findViewById(android.R.id.content);
+ FrameLayout contentRoot = (FrameLayout) mEnclosingLayout.findViewById(android.R.id.content);
// If something went wrong and we were not able to initialize the content root,
// just add a frame layout inside this and return.
if (contentRoot == null) {
contentRoot = new FrameLayout(context);
- contentRoot.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT,
- LayoutParams.MATCH_PARENT));
- parentView.addView(contentRoot);
+ setMatchParent(contentRoot);
+ mEnclosingLayout.addView(contentRoot);
mContentRoot = contentRoot;
} else {
mContentRoot = contentRoot;
@@ -112,70 +125,49 @@
}
}
+ private void setMatchParent(View view) {
+ view.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT,
+ LayoutParams.MATCH_PARENT));
+ }
+
/**
* Creates a Popup and adds it to the content frame. It also adds another {@link FrameLayout} to
* the content frame which shall serve as the new content root.
*/
public void createMenuPopup() {
- assert mContentRoot.getId() == android.R.id.content
+ assert mEnclosingLayout.getChildCount() == 1
: "Action Bar Menus have already been created.";
if (!isOverflowPopupNeeded()) {
return;
}
- // Create a layout to hold the menus and the user's content.
- RelativeLayout layout = new RelativeLayout(mActionBar.getPopupContext());
- layout.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT,
- LayoutParams.MATCH_PARENT));
- mContentRoot.addView(layout);
- // Create a layout for the user's content.
- FrameLayout contentRoot = new FrameLayout(mBridgeContext);
- contentRoot.setLayoutParams(new LayoutParams(
- LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
- // Add contentRoot and menus to the layout.
- layout.addView(contentRoot);
- layout.addView(createMenuView());
- // ContentRoot is now the view we just created.
- mContentRoot = contentRoot;
- }
-
- /**
- * Returns a {@link LinearLayout} containing the menu list view to be embedded in a
- * {@link RelativeLayout}
- */
- @NonNull
- private View createMenuView() {
DisplayMetrics metrics = mBridgeContext.getMetrics();
MenuBuilder menu = mActionBar.getMenuBuilder();
OverflowMenuAdapter adapter = new OverflowMenuAdapter(menu, mActionBar.getPopupContext());
- LinearLayout layout = new LinearLayout(mActionBar.getPopupContext());
+ ListView listView = new ListView(mActionBar.getPopupContext(), null,
+ R.attr.dropDownListViewStyle);
RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(
measureContentWidth(adapter), LayoutParams.WRAP_CONTENT);
layoutParams.addRule(RelativeLayout.ALIGN_PARENT_END);
if (mActionBar.isSplit()) {
layoutParams.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
- // TODO: Find correct value instead of hardcoded 10dp.
- layoutParams.bottomMargin = getPixelValue("-10dp", metrics);
+ layoutParams.bottomMargin = getActionBarHeight() + mActionBar.getMenuPopupMargin();
} else {
- layoutParams.topMargin = getPixelValue("-10dp", metrics);
+ layoutParams.addRule(RelativeLayout.ALIGN_PARENT_TOP);
+ layoutParams.topMargin = getActionBarHeight() + mActionBar.getMenuPopupMargin();
}
- layout.setLayoutParams(layoutParams);
+ layoutParams.setMarginEnd(getPixelValue("5dp", metrics));
+ listView.setLayoutParams(layoutParams);
+ listView.setAdapter(adapter);
final TypedArray a = mActionBar.getPopupContext().obtainStyledAttributes(null,
R.styleable.PopupWindow, R.attr.popupMenuStyle, 0);
- layout.setBackground(a.getDrawable(R.styleable.PopupWindow_popupBackground));
- layout.setDividerDrawable(a.getDrawable(R.attr.actionBarDivider));
+ listView.setBackground(a.getDrawable(R.styleable.PopupWindow_popupBackground));
+ listView.setDivider(a.getDrawable(R.attr.actionBarDivider));
a.recycle();
- layout.setOrientation(LinearLayout.VERTICAL);
- layout.setDividerPadding(getPixelValue("12dp", metrics));
- layout.setShowDividers(LinearLayout.SHOW_DIVIDER_MIDDLE);
-
- ListView listView = new ListView(mActionBar.getPopupContext(), null,
- R.attr.dropDownListViewStyle);
- listView.setAdapter(adapter);
- layout.addView(listView);
- return layout;
+ listView.setElevation(mActionBar.getMenuPopupElevation());
+ mEnclosingLayout.addView(listView);
}
private boolean isOverflowPopupNeeded() {
@@ -244,9 +236,30 @@
return maxWidth;
}
- private int getPixelValue(@NonNull String value, @NonNull DisplayMetrics metrics) {
+ static int getPixelValue(@NonNull String value, @NonNull DisplayMetrics metrics) {
TypedValue typedValue = ResourceHelper.getValue(null, value, false /*requireUnit*/);
return (int) typedValue.getDimension(metrics);
}
+ // TODO: This is duplicated from RenderSessionImpl.
+ private int getActionBarHeight() {
+ RenderResources resources = mBridgeContext.getRenderResources();
+ DisplayMetrics metrics = mBridgeContext.getMetrics();
+ ResourceValue value = resources.findItemInTheme("actionBarSize", true);
+
+ // resolve it
+ value = resources.resolveResValue(value);
+
+ if (value != null) {
+ // get the numerical value, if available
+ TypedValue typedValue = ResourceHelper.getValue("actionBarSize", value.getValue(),
+ true);
+ if (typedValue != null) {
+ // compute the pixel value based on the display metrics
+ return (int) typedValue.getDimension(metrics);
+
+ }
+ }
+ return 0;
+ }
}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/CustomActionBarWrapper.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/CustomActionBarWrapper.java
index 70b9cc3..6db722e 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/CustomActionBarWrapper.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/CustomActionBarWrapper.java
@@ -65,18 +65,17 @@
* Returns a wrapper around different implementations of the Action Bar to provide a common API.
*
* @param decorContent the top level view returned by inflating
- * ?attr/windowActionBarFullscreenDecorLayout
+ * ?attr/windowActionBarFullscreenDecorLayout
*/
@NonNull
public static CustomActionBarWrapper getActionBarWrapper(@NonNull BridgeContext context,
@NonNull SessionParams params, @NonNull View decorContent) {
View view = decorContent.findViewById(R.id.action_bar);
if (view instanceof Toolbar) {
- return new ToolbarWrapper(context, params, ((Toolbar) view)
- );
+ return new ToolbarWrapper(context, params, ((Toolbar) view));
} else if (view instanceof ActionBarView) {
- return new WindowActionBarWrapper(context, params, decorContent, ((ActionBarView) view)
- );
+ return new WindowActionBarWrapper(context, params, decorContent,
+ ((ActionBarView) view));
} else {
throw new IllegalStateException("Can't make an action bar out of " +
view.getClass().getSimpleName());
@@ -174,6 +173,13 @@
@NonNull
abstract DecorToolbar getDecorToolbar();
+ abstract int getMenuPopupElevation();
+
+ /**
+ * Margin between the menu popup and the action bar.
+ */
+ abstract int getMenuPopupMargin();
+
// ---- The implementations ----
/**
@@ -226,25 +232,38 @@
DecorToolbar getDecorToolbar() {
return mToolbar.getWrapper();
}
+
+ @Override
+ int getMenuPopupElevation() {
+ return 10;
+ }
+
+ @Override
+ int getMenuPopupMargin() {
+ return 0;
+ }
}
/**
* Holo theme uses {@link WindowDecorActionBar} as the action bar. This wrapper provides
* access to it using a common API.
*/
- private static class WindowActionBarWrapper extends CustomActionBarWrapper{
+ private static class WindowActionBarWrapper extends CustomActionBarWrapper {
@NonNull
private final WindowDecorActionBar mActionBar;
+ @NonNull
private final ActionBarView mActionBarView;
+ @NonNull
+ private final View mDecorContentRoot;
private MenuBuilder mMenuBuilder;
public WindowActionBarWrapper(@NonNull BridgeContext context, @NonNull SessionParams params,
@NonNull View decorContentRoot, @NonNull ActionBarView actionBarView) {
- super(context, params, new WindowDecorActionBar(decorContentRoot)
- );
+ super(context, params, new WindowDecorActionBar(decorContentRoot));
mActionBarView = actionBarView;
mActionBar = ((WindowDecorActionBar) super.mActionBar);
+ mDecorContentRoot = decorContentRoot;
}
@Override
@@ -270,7 +289,7 @@
}
// Set action bar to be split, if needed.
- ViewGroup splitView = (ViewGroup) mActionBarView.findViewById(R.id.split_action_bar);
+ ViewGroup splitView = (ViewGroup) mDecorContentRoot.findViewById(R.id.split_action_bar);
if (splitView != null) {
mActionBarView.setSplitView(splitView);
Resources res = mContext.getResources();
@@ -314,6 +333,16 @@
return mActionBarView;
}
+ @Override
+ int getMenuPopupElevation() {
+ return 0;
+ }
+
+ @Override
+ int getMenuPopupMargin() {
+ return -ActionBarLayout.getPixelValue("10dp", mContext.getMetrics());
+ }
+
// TODO: Use an adapter, like List View to set up tabs.
@SuppressWarnings("deprecation") // For Tab
private void setupTabs(int num) {
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderDrawable.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderDrawable.java
index b677131..669e6b5 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderDrawable.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderDrawable.java
@@ -57,63 +57,59 @@
public Result render() {
checkLock();
- try {
- // get the drawable resource value
- DrawableParams params = getParams();
- HardwareConfig hardwareConfig = params.getHardwareConfig();
- ResourceValue drawableResource = params.getDrawable();
+ // get the drawable resource value
+ DrawableParams params = getParams();
+ HardwareConfig hardwareConfig = params.getHardwareConfig();
+ ResourceValue drawableResource = params.getDrawable();
- // resolve it
- BridgeContext context = getContext();
- drawableResource = context.getRenderResources().resolveResValue(drawableResource);
+ // resolve it
+ BridgeContext context = getContext();
+ drawableResource = context.getRenderResources().resolveResValue(drawableResource);
- if (drawableResource == null ||
- drawableResource.getResourceType() != ResourceType.DRAWABLE) {
- return Status.ERROR_NOT_A_DRAWABLE.createResult();
- }
-
- // create a simple FrameLayout
- FrameLayout content = new FrameLayout(context);
-
- // get the actual Drawable object to draw
- Drawable d = ResourceHelper.getDrawable(drawableResource, context);
- content.setBackground(d);
-
- // set the AttachInfo on the root view.
- AttachInfo_Accessor.setAttachInfo(content);
-
-
- // measure
- int w = hardwareConfig.getScreenWidth();
- int h = hardwareConfig.getScreenHeight();
- int w_spec = MeasureSpec.makeMeasureSpec(w, MeasureSpec.EXACTLY);
- int h_spec = MeasureSpec.makeMeasureSpec(h, MeasureSpec.EXACTLY);
- content.measure(w_spec, h_spec);
-
- // now do the layout.
- content.layout(0, 0, w, h);
-
- // preDraw setup
- AttachInfo_Accessor.dispatchOnPreDraw(content);
-
- // draw into a new image
- BufferedImage image = getImage(w, h);
-
- // create an Android bitmap around the BufferedImage
- Bitmap bitmap = Bitmap_Delegate.createBitmap(image,
- true /*isMutable*/, hardwareConfig.getDensity());
-
- // create a Canvas around the Android bitmap
- Canvas canvas = new Canvas(bitmap);
- canvas.setDensity(hardwareConfig.getDensity().getDpiValue());
-
- // and draw
- content.draw(canvas);
-
- return Status.SUCCESS.createResult(image);
- } catch (IOException e) {
- return ERROR_UNKNOWN.createResult(e.getMessage(), e);
+ if (drawableResource == null ||
+ drawableResource.getResourceType() != ResourceType.DRAWABLE) {
+ return Status.ERROR_NOT_A_DRAWABLE.createResult();
}
+
+ // create a simple FrameLayout
+ FrameLayout content = new FrameLayout(context);
+
+ // get the actual Drawable object to draw
+ Drawable d = ResourceHelper.getDrawable(drawableResource, context);
+ content.setBackground(d);
+
+ // set the AttachInfo on the root view.
+ AttachInfo_Accessor.setAttachInfo(content);
+
+
+ // measure
+ int w = hardwareConfig.getScreenWidth();
+ int h = hardwareConfig.getScreenHeight();
+ int w_spec = MeasureSpec.makeMeasureSpec(w, MeasureSpec.EXACTLY);
+ int h_spec = MeasureSpec.makeMeasureSpec(h, MeasureSpec.EXACTLY);
+ content.measure(w_spec, h_spec);
+
+ // now do the layout.
+ content.layout(0, 0, w, h);
+
+ // preDraw setup
+ AttachInfo_Accessor.dispatchOnPreDraw(content);
+
+ // draw into a new image
+ BufferedImage image = getImage(w, h);
+
+ // create an Android bitmap around the BufferedImage
+ Bitmap bitmap = Bitmap_Delegate.createBitmap(image,
+ true /*isMutable*/, hardwareConfig.getDensity());
+
+ // create a Canvas around the Android bitmap
+ Canvas canvas = new Canvas(bitmap);
+ canvas.setDensity(hardwareConfig.getDensity().getDpiValue());
+
+ // and draw
+ content.draw(canvas);
+
+ return Status.SUCCESS.createResult(image);
}
protected BufferedImage getImage(int w, int h) {
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderSessionImpl.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderSessionImpl.java
index a2eed9a..20eddd6 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderSessionImpl.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderSessionImpl.java
@@ -1571,7 +1571,7 @@
return null;
}
- private void invalidateRenderingSize() {
+ public void invalidateRenderingSize() {
mMeasuredScreenWidth = mMeasuredScreenHeight = -1;
}
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/CreateInfo.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/CreateInfo.java
index 2fcdf34..6340059 100644
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/CreateInfo.java
+++ b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/CreateInfo.java
@@ -162,6 +162,11 @@
"android.view.WindowManagerGlobal#getWindowManagerService",
"android.view.inputmethod.InputMethodManager#getInstance",
"android.view.MenuInflater#registerMenu",
+ "android.view.RenderNode#nCreate",
+ "android.view.RenderNode#nDestroyRenderNode",
+ "android.view.RenderNode#nSetElevation",
+ "android.view.RenderNode#nGetElevation",
+ "android.view.ViewGroup#drawChild",
"com.android.internal.view.menu.MenuBuilder#createNewMenuItem",
"com.android.internal.util.XmlUtils#convertValueToInt",
"com.android.internal.textservice.ITextServicesManager$Stub#asInterface",
@@ -216,7 +221,6 @@
"android.text.AndroidBidi",
"android.text.StaticLayout",
"android.text.format.Time",
- "android.util.FloatMath",
"android.view.Display",
"libcore.icu.DateIntervalFormat",
"libcore.icu.ICU",
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/DelegateClassAdapter.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/DelegateClassAdapter.java
index 3d89c68..ae4a57d 100644
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/DelegateClassAdapter.java
+++ b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/DelegateClassAdapter.java
@@ -112,6 +112,7 @@
// The implementation of this 'delegate' method is done in layoutlib_bridge.
int accessDelegate = access;
+ access = access & ~Opcodes.ACC_PRIVATE; // If private, make it package protected.
MethodVisitor mwOriginal = super.visitMethod(access, name + ORIGINAL_SUFFIX,
desc, signature, exceptions);
diff --git a/tools/obbtool/Android.mk b/tools/obbtool/Android.mk
index 9ff56d6..99a5671 100644
--- a/tools/obbtool/Android.mk
+++ b/tools/obbtool/Android.mk
@@ -13,7 +13,7 @@
LOCAL_SRC_FILES := \
Main.cpp
-LOCAL_CFLAGS := -Wall -Werror
+LOCAL_CFLAGS := -Wall -Werror -Wno-mismatched-tags
#LOCAL_C_INCLUDES +=
@@ -36,7 +36,7 @@
LOCAL_MODULE := pbkdf2gen
LOCAL_MODULE_TAGS := optional
-LOCAL_CFLAGS := -Wall -Werror
+LOCAL_CFLAGS := -Wall -Werror -Wno-mismatched-tags
LOCAL_SRC_FILES := pbkdf2gen.cpp
LOCAL_LDLIBS += -ldl
LOCAL_C_INCLUDES := external/openssl/include $(LOCAL_C_INCLUDES)
diff --git a/tools/obbtool/Main.cpp b/tools/obbtool/Main.cpp
index b2152e8..64808c0 100644
--- a/tools/obbtool/Main.cpp
+++ b/tools/obbtool/Main.cpp
@@ -89,7 +89,7 @@
" Prints the OBB signature information of a file.\n\n", gProgName);
}
-void doAdd(const char* filename, struct PackageInfo* info) {
+void doAdd(const char* filename, PackageInfo* info) {
ObbFile *obb = new ObbFile();
if (obb->readFrom(filename)) {
fprintf(stderr, "ERROR: %s: OBB signature already present\n", filename);
@@ -182,7 +182,7 @@
{
int opt;
int option_index = 0;
- struct PackageInfo package_info;
+ PackageInfo package_info;
int result = 1; // pessimistically assume an error.
diff --git a/tools/split-select/RuleGenerator.cpp b/tools/split-select/RuleGenerator.cpp
index 72bb0c7..83c9795 100644
--- a/tools/split-select/RuleGenerator.cpp
+++ b/tools/split-select/RuleGenerator.cpp
@@ -38,7 +38,7 @@
densityRule->op = Rule::AND_SUBRULES;
const bool hasAnyDensity = std::find(allDensities.begin(),
- allDensities.end(), ResTable_config::DENSITY_ANY) != allDensities.end();
+ allDensities.end(), (int) ResTable_config::DENSITY_ANY) != allDensities.end();
if (hasAnyDensity) {
sp<Rule> version = new Rule();
diff --git a/tools/split-select/RuleGenerator_test.cpp b/tools/split-select/RuleGenerator_test.cpp
index 778d604..470cadc 100644
--- a/tools/split-select/RuleGenerator_test.cpp
+++ b/tools/split-select/RuleGenerator_test.cpp
@@ -47,10 +47,10 @@
}
TEST(RuleGeneratorTest, densityConstantsAreSane) {
- EXPECT_LT(263, ConfigDescription::DENSITY_XHIGH);
- EXPECT_GT(262, ConfigDescription::DENSITY_HIGH);
- EXPECT_LT(363, ConfigDescription::DENSITY_XXHIGH);
- EXPECT_GT(362, ConfigDescription::DENSITY_XHIGH);
+ EXPECT_LT(263, (int) ConfigDescription::DENSITY_XHIGH);
+ EXPECT_GT(262, (int) ConfigDescription::DENSITY_HIGH);
+ EXPECT_LT(363, (int) ConfigDescription::DENSITY_XXHIGH);
+ EXPECT_GT(362, (int) ConfigDescription::DENSITY_XHIGH);
}
TEST(RuleGeneratorTest, testDensityRules) {
diff --git a/tools/split-select/TestRules.cpp b/tools/split-select/TestRules.cpp
index f980dc4..86ccd6a 100644
--- a/tools/split-select/TestRules.cpp
+++ b/tools/split-select/TestRules.cpp
@@ -75,7 +75,7 @@
const char*, const char*,
const sp<Rule>& actual, const Rule& expected) {
const String8 expectedStr(expected.toJson());
- const String8 actualStr(actual != NULL ? actual->toJson() : "");
+ const String8 actualStr(actual != NULL ? actual->toJson() : String8());
if (expectedStr != actualStr) {
return ::testing::AssertionFailure()
diff --git a/wifi/java/android/net/wifi/ScanResult.java b/wifi/java/android/net/wifi/ScanResult.java
index 9729c91..994f180 100644
--- a/wifi/java/android/net/wifi/ScanResult.java
+++ b/wifi/java/android/net/wifi/ScanResult.java
@@ -16,6 +16,8 @@
package android.net.wifi;
+import android.net.wifi.passpoint.WifiPasspointInfo;
+import android.net.wifi.passpoint.WifiPasspointManager;
import android.os.Parcel;
import android.os.Parcelable;
@@ -169,6 +171,13 @@
public int distanceSdCm;
/**
+ * Passpoint ANQP information. This is not fetched automatically.
+ * Use {@link WifiPasspointManager#requestAnqpInfo} to request ANQP info.
+ * {@hide}
+ */
+ public WifiPasspointInfo passpoint;
+
+ /**
* {@hide}
*/
public final static int UNSPECIFIED = -1;
@@ -264,6 +273,7 @@
distanceCm = source.distanceCm;
distanceSdCm = source.distanceSdCm;
seen = source.seen;
+ passpoint = source.passpoint;
autoJoinStatus = source.autoJoinStatus;
untrusted = source.untrusted;
numConnection = source.numConnection;
@@ -303,6 +313,7 @@
sb.append(", distanceSd: ").append((distanceSdCm != UNSPECIFIED ? distanceSdCm : "?")).
append("(cm)");
+ sb.append(", passpoint: ").append(passpoint != null ? "yes" : "no");
if (autoJoinStatus != 0) {
sb.append(", status: ").append(autoJoinStatus);
}
@@ -336,6 +347,12 @@
dest.writeInt(numUsage);
dest.writeInt(numIpConfigFailures);
dest.writeInt(isAutoJoinCandidate);
+ if (passpoint != null) {
+ dest.writeInt(1);
+ passpoint.writeToParcel(dest, flags);
+ } else {
+ dest.writeInt(0);
+ }
if (informationElements != null) {
dest.writeInt(informationElements.length);
for (int i = 0; i < informationElements.length; i++) {
@@ -373,6 +390,9 @@
sr.numUsage = in.readInt();
sr.numIpConfigFailures = in.readInt();
sr.isAutoJoinCandidate = in.readInt();
+ if (in.readInt() == 1) {
+ sr.passpoint = WifiPasspointInfo.CREATOR.createFromParcel(in);
+ }
int n = in.readInt();
if (n != 0) {
sr.informationElements = new InformationElement[n];
diff --git a/wifi/java/android/net/wifi/WifiConfiguration.java b/wifi/java/android/net/wifi/WifiConfiguration.java
index 0457dda..84da72c 100644
--- a/wifi/java/android/net/wifi/WifiConfiguration.java
+++ b/wifi/java/android/net/wifi/WifiConfiguration.java
@@ -17,6 +17,7 @@
package android.net.wifi;
import android.annotation.SystemApi;
+import android.content.pm.PackageManager;
import android.net.IpConfiguration;
import android.net.IpConfiguration.ProxySettings;
import android.net.IpConfiguration.IpAssignment;
@@ -378,12 +379,34 @@
/**
* @hide
+ * Universal name for app creating the configuration
+ * see {#link {@link PackageManager#getNameForUid(int)}
+ */
+ @SystemApi
+ public String creatorName;
+
+ /**
+ * @hide
+ * Universal name for app updating the configuration
+ * see {#link {@link PackageManager#getNameForUid(int)}
+ */
+ @SystemApi
+ public String lastUpdateName;
+
+ /**
+ * @hide
* Uid used by autoJoin
*/
public String autoJoinBSSID;
/**
* @hide
+ * Status of user approval for connection
+ */
+ public int userApproved = USER_UNSPECIFIED;
+
+ /**
+ * @hide
* BSSID list on which this configuration was seen.
* TODO: prevent this list to grow infinitely, age-out the results
*/
@@ -617,6 +640,28 @@
/** @hide */
public static final int AUTO_JOIN_DELETED = 200;
+ // States for the userApproved field
+ /**
+ * @hide
+ * User hasn't specified if connection is okay
+ */
+ public static final int USER_UNSPECIFIED = 0;
+ /**
+ * @hide
+ * User has approved this for connection
+ */
+ public static final int USER_APPROVED = 1;
+ /**
+ * @hide
+ * User has banned this from connection
+ */
+ public static final int USER_BANNED = 2;
+ /**
+ * @hide
+ * Waiting for user input
+ */
+ public static final int USER_PENDING = 3;
+
/**
* @hide
*/
@@ -845,6 +890,8 @@
ephemeral = false;
validatedInternetAccess = false;
mIpConfiguration = new IpConfiguration();
+ lastUpdateUid = -1;
+ creatorUid = -1;
}
/**
@@ -889,6 +936,15 @@
}
/**
+ * Helper function, idenfity if a configuration should be treated as an enterprise network
+ * @hide
+ */
+ public boolean isEnterprise() {
+ return allowedKeyManagement.get(KeyMgmt.WPA_EAP) ||
+ allowedKeyManagement.get(KeyMgmt.IEEE8021X);
+ }
+
+ /**
* most recent time we have seen this configuration
* @return most recent scanResult
* @hide
@@ -1069,7 +1125,6 @@
sbuf.append("IP config:\n");
sbuf.append(mIpConfiguration.toString());
- if (this.creatorUid != 0) sbuf.append(" uid=" + Integer.toString(creatorUid));
if (this.autoJoinBSSID != null) sbuf.append(" autoJoinBSSID=" + autoJoinBSSID);
long now_ms = System.currentTimeMillis();
if (this.blackListTimestamp != 0) {
@@ -1081,6 +1136,12 @@
sbuf.append(" blackListed: ").append(Long.toString(diff/1000)).append( "sec");
}
}
+ if (creatorUid != 0) sbuf.append(" cuid=" + Integer.toString(creatorUid));
+ if (creatorName != null) sbuf.append(" cname=" + creatorName);
+ if (lastUpdateUid != 0) sbuf.append(" luid=" + lastUpdateUid);
+ if (lastUpdateName != null) sbuf.append(" lname=" + lastUpdateName);
+ sbuf.append("userApproved=" + userApprovedAsString(userApproved));
+
if (this.lastConnected != 0) {
sbuf.append('\n');
long diff = now_ms - this.lastConnected;
@@ -1205,6 +1266,20 @@
return SSID;
}
+ /** @hide **/
+ public static String userApprovedAsString(int userApproved) {
+ switch (userApproved) {
+ case USER_APPROVED:
+ return "USER_APPROVED";
+ case USER_BANNED:
+ return "USER_BANNED";
+ case USER_UNSPECIFIED:
+ return "USER_UNSPECIFIED";
+ default:
+ return "INVALID";
+ }
+ }
+
/**
* Get an identifier for associating credentials with this config
* @param current configuration contains values for additional fields
@@ -1465,6 +1540,8 @@
lastConnectUid = source.lastConnectUid;
lastUpdateUid = source.lastUpdateUid;
creatorUid = source.creatorUid;
+ creatorName = source.creatorName;
+ lastUpdateName = source.lastUpdateName;
peerWifiConfiguration = source.peerWifiConfiguration;
blackListTimestamp = source.blackListTimestamp;
lastConnected = source.lastConnected;
@@ -1488,6 +1565,7 @@
= source.autoJoinUseAggressiveJoinAttemptThreshold;
autoJoinBailedDueToLowRssi = source.autoJoinBailedDueToLowRssi;
dirty = source.dirty;
+ userApproved = source.userApproved;
numNoInternetAccessReports = source.numNoInternetAccessReports;
}
}
@@ -1537,6 +1615,8 @@
dest.writeInt(creatorUid);
dest.writeInt(lastConnectUid);
dest.writeInt(lastUpdateUid);
+ dest.writeString(creatorName);
+ dest.writeString(lastUpdateName);
dest.writeLong(blackListTimestamp);
dest.writeLong(lastConnectionFailure);
dest.writeInt(numConnectionFailures);
@@ -1554,6 +1634,7 @@
dest.writeInt(numUserTriggeredJoinAttempts);
dest.writeInt(autoJoinUseAggressiveJoinAttemptThreshold);
dest.writeInt(autoJoinBailedDueToLowRssi ? 1 : 0);
+ dest.writeInt(userApproved);
dest.writeInt(numNoInternetAccessReports);
}
@@ -1599,6 +1680,8 @@
config.creatorUid = in.readInt();
config.lastConnectUid = in.readInt();
config.lastUpdateUid = in.readInt();
+ config.creatorName = in.readString();
+ config.lastUpdateName = in.readString();
config.blackListTimestamp = in.readLong();
config.lastConnectionFailure = in.readLong();
config.numConnectionFailures = in.readInt();
@@ -1616,6 +1699,7 @@
config.numUserTriggeredJoinAttempts = in.readInt();
config.autoJoinUseAggressiveJoinAttemptThreshold = in.readInt();
config.autoJoinBailedDueToLowRssi = in.readInt() != 0;
+ config.userApproved = in.readInt();
config.numNoInternetAccessReports = in.readInt();
return config;
}
diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java
index 1393bce..6559287 100644
--- a/wifi/java/android/net/wifi/WifiManager.java
+++ b/wifi/java/android/net/wifi/WifiManager.java
@@ -86,6 +86,28 @@
public static final String EXTRA_SCAN_AVAILABLE = "scan_enabled";
/**
+ * Broadcast intent action indicating that the credential of a Wi-Fi network
+ * has been changed. One extra provides the ssid of the network. Another
+ * extra provides the event type, whether the credential is saved or forgot.
+ * @hide
+ */
+ @SystemApi
+ public static final String WIFI_CREDENTIAL_CHANGED_ACTION =
+ "android.net.wifi.WIFI_CREDENTIAL_CHANGED";
+ /** @hide */
+ @SystemApi
+ public static final String EXTRA_WIFI_CREDENTIAL_EVENT_TYPE = "et";
+ /** @hide */
+ @SystemApi
+ public static final String EXTRA_WIFI_CREDENTIAL_SSID = "ssid";
+ /** @hide */
+ @SystemApi
+ public static final int WIFI_CREDENTIAL_SAVED = 0;
+ /** @hide */
+ @SystemApi
+ public static final int WIFI_CREDENTIAL_FORGOT = 1;
+
+ /**
* Broadcast intent action indicating that Wi-Fi has been enabled, disabled,
* enabling, disabling, or unknown. One extra provides this state as an int.
* Another extra provides the previous state, if available.
diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pWfdInfo.java b/wifi/java/android/net/wifi/p2p/WifiP2pWfdInfo.java
index d65d03e..92c7e36 100644
--- a/wifi/java/android/net/wifi/p2p/WifiP2pWfdInfo.java
+++ b/wifi/java/android/net/wifi/p2p/WifiP2pWfdInfo.java
@@ -77,6 +77,7 @@
public boolean setDeviceType(int deviceType) {
if (deviceType >= WFD_SOURCE && deviceType <= SOURCE_OR_PRIMARY_SINK) {
+ mDeviceInfo &= ~DEVICE_TYPE;
mDeviceInfo |= deviceType;
return true;
}
diff --git a/wifi/java/android/net/wifi/passpoint/IWifiPasspointManager.aidl b/wifi/java/android/net/wifi/passpoint/IWifiPasspointManager.aidl
new file mode 100644
index 0000000..50bec33
--- /dev/null
+++ b/wifi/java/android/net/wifi/passpoint/IWifiPasspointManager.aidl
@@ -0,0 +1,45 @@
+/**
+ * Copyright (c) 2014, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net.wifi.passpoint;
+
+import android.net.wifi.ScanResult;
+import android.net.wifi.passpoint.WifiPasspointPolicy;
+import android.net.wifi.passpoint.WifiPasspointCredential;
+import android.os.Messenger;
+
+/**
+ * Interface that allows controlling and querying Wifi Passpoint connectivity.
+ *
+ * {@hide}
+ */
+interface IWifiPasspointManager
+{
+ Messenger getMessenger();
+
+ int getPasspointState();
+
+ List<WifiPasspointPolicy> requestCredentialMatch(in List<ScanResult> requested);
+
+ List<WifiPasspointCredential> getCredentials();
+
+ boolean addCredential(in WifiPasspointCredential cred);
+
+ boolean updateCredential(in WifiPasspointCredential cred);
+
+ boolean removeCredential(in WifiPasspointCredential cred);
+}
+
diff --git a/cmds/app_process/sigchain_proxy.cpp b/wifi/java/android/net/wifi/passpoint/WifiPasspointCredential.aidl
similarity index 73%
copy from cmds/app_process/sigchain_proxy.cpp
copy to wifi/java/android/net/wifi/passpoint/WifiPasspointCredential.aidl
index bb7a678..cfd3605 100644
--- a/cmds/app_process/sigchain_proxy.cpp
+++ b/wifi/java/android/net/wifi/passpoint/WifiPasspointCredential.aidl
@@ -1,11 +1,11 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
+/**
+ * Copyright (c) 2014, The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
- * http://www.apache.org/licenses/LICENSE-2.0
+ * 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,
@@ -14,4 +14,6 @@
* limitations under the License.
*/
-#include "sigchainlib/sigchain.cc"
+package android.net.wifi.passpoint;
+
+parcelable WifiPasspointCredential;
diff --git a/wifi/java/android/net/wifi/passpoint/WifiPasspointCredential.java b/wifi/java/android/net/wifi/passpoint/WifiPasspointCredential.java
new file mode 100644
index 0000000..0a7230f
--- /dev/null
+++ b/wifi/java/android/net/wifi/passpoint/WifiPasspointCredential.java
@@ -0,0 +1,667 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net.wifi.passpoint;
+
+import android.net.wifi.WifiEnterpriseConfig;
+import android.os.Parcelable;
+import android.os.Parcel;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+
+
+/**
+ * A class representing a Wi-Fi Passpoint credential.
+ * @hide
+ */
+public class WifiPasspointCredential implements Parcelable {
+
+ private final static String TAG = "PasspointCredential";
+ private final static boolean DBG = true;
+
+ /** Wi-Fi nodes**/
+ private String mWifiSpFqdn;
+
+ /** PerProviderSubscription nodes **/
+ private String mCredentialName;
+
+ /** SubscriptionUpdate nodes **/
+ private String mSubscriptionUpdateInterval;
+ private String mSubscriptionUpdateMethod;
+ private String mSubscriptionUpdateRestriction;
+ private String mSubscriptionUpdateURI;
+ private String mSubscriptionUpdateUsername;
+ private String mSubscriptionUpdatePassword;
+
+ /** HomeSP nodes **/
+ private String mHomeSpFqdn;
+ private String mFriendlyName;
+ private Collection<WifiPasspointDmTree.HomeOIList> mHomeOIList;
+ private Collection<WifiPasspointDmTree.OtherHomePartners> mOtherHomePartnerList;
+
+ /** SubscriptionParameters nodes**/
+ private String mCreationDate;
+ private String mExpirationDate;
+
+ /** Credential nodes **/
+ private String mType;
+ private String mInnerMethod;
+ private String mCertType;
+ private String mCertSha256Fingerprint;
+ private String mUpdateIdentifier;
+ private String mUsername;
+ private String mPasswd;
+ private String mRealm;
+ private String mImsi;
+ private String mMcc;
+ private String mMnc;
+ private String mCaRootCert;
+ private String mClientCert;
+ private boolean mCheckAaaServerCertStatus;
+
+ /** Policy nodes **/
+ private String mPolicyUpdateUri;
+ private String mPolicyUpdateInterval;
+ private String mPolicyUpdateUsername;
+ private String mPolicyUpdatePassword;
+ private String mPolicyUpdateRestriction;
+ private String mPolicyUpdateMethod;
+ private Collection<WifiPasspointDmTree.PreferredRoamingPartnerList> mPreferredRoamingPartnerList;
+ private Collection<WifiPasspointDmTree.MinBackhaulThresholdNetwork> mMinBackhaulThresholdNetwork;
+ private Collection<WifiPasspointDmTree.SPExclusionList> mSpExclusionList;
+ private Collection<WifiPasspointDmTree.RequiredProtoPortTuple> mRequiredProtoPortTuple;
+ private String mMaxBssLoad;
+
+ /** CrednetialPriority node **/
+ private int mCrednetialPriority;
+
+ /** AAAServerTrustRoot nodes **/
+ private String mAaaCertUrl;
+ private String mAaaSha256Fingerprint;
+
+ /** Others **/
+ private boolean mIsMachineRemediation;
+ private boolean mUserPreferred = false;
+ private String mWifiTreePath;
+ private WifiEnterpriseConfig mEnterpriseConfig;
+
+ /** @hide */
+ public WifiPasspointCredential() {}
+
+ /**
+ * Constructor
+ * @param realm Realm of the passpoint credential
+ * @param fqdn Fully qualified domain name (FQDN) of the credential
+ * @param config Enterprise config, must be either EAP-TLS or EAP-TTLS
+ * @see WifiEnterpriseConfig
+ */
+ public WifiPasspointCredential(String realm, String fqdn, WifiEnterpriseConfig config) {
+ mRealm = realm;
+ switch (config.getEapMethod()) {
+ case WifiEnterpriseConfig.Eap.TLS:
+ case WifiEnterpriseConfig.Eap.TTLS:
+ mEnterpriseConfig = new WifiEnterpriseConfig(config);
+ break;
+ default:
+ // ignore
+ }
+ }
+
+ /** @hide */
+ public WifiPasspointCredential(String type,
+ String caroot,
+ String clientcert,
+ String mcc,
+ String mnc,
+ WifiPasspointDmTree.SpFqdn sp,
+ WifiPasspointDmTree.CredentialInfo credinfo) {
+
+ if (credinfo == null) {
+ return;
+ }
+
+ mType = type;
+ mCaRootCert = caroot;
+ mClientCert = clientcert;
+
+ mWifiSpFqdn = sp.nodeName;
+ mUpdateIdentifier = sp.perProviderSubscription.UpdateIdentifier;
+
+ mCredentialName = credinfo.nodeName;
+ mOtherHomePartnerList = credinfo.homeSP.otherHomePartners.values();
+
+ Set set = credinfo.aAAServerTrustRoot.entrySet();
+ Iterator i = set.iterator();
+ if (i.hasNext()) {
+ Map.Entry entry3 = (Map.Entry) i.next();
+ WifiPasspointDmTree.AAAServerTrustRoot aaa = (WifiPasspointDmTree.AAAServerTrustRoot) entry3.getValue();
+ mAaaCertUrl = aaa.CertURL;
+ mAaaSha256Fingerprint = aaa.CertSHA256Fingerprint;
+ }
+
+ mCertType = credinfo.credential.digitalCertificate.CertificateType;
+ mCertSha256Fingerprint = credinfo.credential.digitalCertificate.CertSHA256Fingerprint;
+ mUsername = credinfo.credential.usernamePassword.Username;
+ mPasswd = credinfo.credential.usernamePassword.Password;
+ mIsMachineRemediation = credinfo.credential.usernamePassword.MachineManaged;
+ mInnerMethod = credinfo.credential.usernamePassword.eAPMethod.InnerMethod;
+ mImsi = credinfo.credential.sim.IMSI;
+ mMcc = mcc;
+ mMnc = mnc;
+ mCreationDate = credinfo.credential.CreationDate;
+ mExpirationDate = credinfo.credential.ExpirationDate;
+ mRealm = credinfo.credential.Realm;
+
+ if (credinfo.credentialPriority == null) {
+ mCrednetialPriority = 128;
+ } else {
+ mCrednetialPriority = Integer.parseInt(credinfo.credentialPriority);
+ }
+
+ mHomeSpFqdn = credinfo.homeSP.FQDN;
+
+ mSubscriptionUpdateInterval = credinfo.subscriptionUpdate.UpdateInterval;
+ mSubscriptionUpdateMethod = credinfo.subscriptionUpdate.UpdateMethod;
+ mSubscriptionUpdateRestriction = credinfo.subscriptionUpdate.Restriction;
+ mSubscriptionUpdateURI = credinfo.subscriptionUpdate.URI;
+ mSubscriptionUpdateUsername = credinfo.subscriptionUpdate.usernamePassword.Username;
+ mSubscriptionUpdatePassword = credinfo.subscriptionUpdate.usernamePassword.Password;
+
+ mPolicyUpdateUri = credinfo.policy.policyUpdate.URI;
+ mPolicyUpdateInterval = credinfo.policy.policyUpdate.UpdateInterval;
+ mPolicyUpdateUsername = credinfo.policy.policyUpdate.usernamePassword.Username;
+ mPolicyUpdatePassword = credinfo.policy.policyUpdate.usernamePassword.Password;
+ mPolicyUpdateRestriction = credinfo.policy.policyUpdate.Restriction;
+ mPolicyUpdateMethod = credinfo.policy.policyUpdate.UpdateMethod;
+ mPreferredRoamingPartnerList = credinfo.policy.preferredRoamingPartnerList.values();
+ mMinBackhaulThresholdNetwork = credinfo.policy.minBackhaulThreshold.values();
+ mRequiredProtoPortTuple = credinfo.policy.requiredProtoPortTuple.values();
+ mMaxBssLoad = credinfo.policy.maximumBSSLoadValue;
+ mSpExclusionList = credinfo.policy.sPExclusionList.values();
+
+ mHomeOIList = credinfo.homeSP.homeOIList.values();
+ mFriendlyName = credinfo.homeSP.FriendlyName;
+ mCheckAaaServerCertStatus = credinfo.credential.CheckAAAServerCertStatus;
+ }
+
+ /** @hide */
+ public String getUpdateIdentifier() {
+ return mUpdateIdentifier;
+ }
+
+ /** @hide */
+ public String getUpdateMethod() {
+ return mSubscriptionUpdateMethod;
+ }
+
+ /** @hide */
+ public void setUpdateMethod(String method) {
+ mSubscriptionUpdateMethod = method;
+ }
+
+ /** @hide */
+ public String getWifiSpFqdn() {
+ return mWifiSpFqdn;
+ }
+
+ /** @hide */
+ public String getCredName() {
+ return mCredentialName;
+ }
+
+ /** @hide */
+ public String getType() {
+ return mType;
+ }
+
+ /**
+ * Get enterprise config of this Passpoint credential.
+ * @return Enterprise config
+ * @see WifiEnterpriseConfig
+ */
+ public WifiEnterpriseConfig getEnterpriseConfig() {
+ return new WifiEnterpriseConfig(mEnterpriseConfig);
+ }
+
+ /**
+ * Set enterprise config of this Passpoint credential.
+ * @param config Enterprise config, must be either EAP-TLS or EAP-TTLS
+ * @see WifiEnterpriseConfig
+ */
+ public void setEnterpriseConfig(WifiEnterpriseConfig config) {
+ // TODO
+ }
+
+ /** @hide */
+ public String getCertType() {
+ return mCertType;
+ }
+
+ /** @hide */
+ public String getCertSha256Fingerprint() {
+ return mCertSha256Fingerprint;
+ }
+
+ /** @hide */
+ public String getUserName() {
+ return mUsername;
+ }
+
+ /** @hide */
+ public String getPassword() {
+ // TODO: guarded by connectivity internal
+ return mPasswd;
+ }
+
+ /** @hide */
+ public String getImsi() {
+ return mImsi;
+ }
+
+ /** @hide */
+ public String getMcc() {
+ return mMcc;
+ }
+
+ /** @hide */
+ public String getMnc() {
+ return mMnc;
+ }
+
+ /** @hide */
+ public String getCaRootCertPath() {
+ return mCaRootCert;
+ }
+
+ /** @hide */
+ public String getClientCertPath() {
+ return mClientCert;
+ }
+
+ /**
+ * Get the realm of this Passpoint credential.
+ * @return Realm
+ */
+ public String getRealm() {
+ return mRealm;
+ }
+
+ /**
+ * Set the ream of this Passpoint credential.
+ * @param realm Realm
+ */
+ public void setRealm(String realm) {
+ mRealm = realm;
+ }
+
+ /** @hide */
+ public int getPriority() {
+ if (mUserPreferred) {
+ return 0;
+ }
+
+ return mCrednetialPriority;
+ }
+
+ /**
+ * Get the fully qualified domain name (FQDN) of this Passpoint credential.
+ * @return FQDN
+ */
+ public String getHomeSpFqdn() {
+ return mHomeSpFqdn;
+ }
+
+ /**
+ * Set the fully qualified domain name (FQDN) of this Passpoint credential.
+ * @param fqdn FQDN
+ */
+ public void setHomeFqdn(String fqdn) {
+ mHomeSpFqdn = fqdn;
+ }
+
+
+ /** @hide */
+ public Collection<WifiPasspointDmTree.OtherHomePartners> getOtherHomePartnerList() {
+ return mOtherHomePartnerList;
+ }
+
+ /** @hide */
+ public String getSubscriptionUpdateUsername() {
+ return mSubscriptionUpdateUsername;
+ }
+
+ /** @hide */
+ public String getSubscriptionUpdatePassword() {
+ return mSubscriptionUpdatePassword;
+ }
+
+ /** @hide */
+ public String getPolicyUpdateUri() {
+ return mPolicyUpdateUri;
+ }
+
+ /** @hide */
+ public String getPolicyUpdateInterval() {
+ return mPolicyUpdateInterval;
+ }
+
+ /** @hide */
+ public String getPolicyUpdateUsername() {
+ return mPolicyUpdateUsername;
+ }
+
+ /** @hide */
+ public String getPolicyUpdatePassword() {
+ return mPolicyUpdatePassword;
+ }
+
+ /** @hide */
+ public String getPolicyUpdateRestriction() {
+ return mPolicyUpdateRestriction;
+ }
+
+ /** @hide */
+ public String getPolicyUpdateMethod() {
+ return mPolicyUpdateMethod;
+ }
+
+ /** @hide */
+ public String getCreationDate() {
+ return mCreationDate;
+ }
+
+ /** @hide */
+ public String getExpirationDate() {
+ return mExpirationDate;
+ }
+
+ /** @hide */
+ public void setExpirationDate(String expirationdate) {
+ mExpirationDate = expirationdate;
+ }
+
+ /** @hide */
+ public Collection<WifiPasspointDmTree.PreferredRoamingPartnerList> getPreferredRoamingPartnerList() {
+ return mPreferredRoamingPartnerList;
+ }
+
+ /** @hide */
+ public Collection<WifiPasspointDmTree.HomeOIList> getHomeOiList() {
+ return mHomeOIList;
+ }
+
+ /** @hide */
+ public Collection<WifiPasspointDmTree.MinBackhaulThresholdNetwork> getBackhaulThresholdList() {
+ return mMinBackhaulThresholdNetwork;
+ }
+
+ /** @hide */
+ public Collection<WifiPasspointDmTree.RequiredProtoPortTuple> getRequiredProtoPortList() {
+ return mRequiredProtoPortTuple;
+ }
+
+ /** @hide */
+ public Collection<WifiPasspointDmTree.SPExclusionList> getSPExclusionList() {
+ return mSpExclusionList;
+ }
+
+ /** @hide */
+ public boolean getIsMachineRemediation() {
+ return mIsMachineRemediation;
+ }
+
+ /** @hide */
+ public String getAaaCertUrl() {
+ return mAaaCertUrl;
+ }
+
+ /** @hide */
+ public String getAaaSha256Fingerprint() {
+ return mAaaSha256Fingerprint;
+ }
+
+ /** @hide */
+ public String getSubscriptionUpdateRestriction() {
+ return mSubscriptionUpdateRestriction;
+ }
+
+ /** @hide */
+ public String getSubscriptionUpdateURI() {
+ return mSubscriptionUpdateURI;
+ }
+
+ /** @hide */
+ public String getSubscriptionUpdateInterval() {
+ return mSubscriptionUpdateInterval;
+ }
+
+ /** @hide */
+ public String getFriendlyName() {
+ return mFriendlyName;
+ }
+
+ /** @hide */
+ public String getMaxBssLoad() {
+ return mMaxBssLoad;
+ }
+
+ /** @hide */
+ public boolean getUserPreference() {
+ return mUserPreferred;
+ }
+
+ /** @hide */
+ public boolean getCheckAaaServerCertStatus() {
+ return mCheckAaaServerCertStatus;
+ }
+
+ /** @hide */
+ public void setUserPreference(boolean value) {
+ mUserPreferred = value;
+ }
+
+ @Override
+ /** @hide */
+ public boolean equals(Object obj) {
+ boolean result = false;
+ if (obj instanceof WifiPasspointCredential) {
+ final WifiPasspointCredential other = (WifiPasspointCredential) obj;
+ if (this.mType.equals(other.mType)) {
+ if (this.mType.equals("TTLS")) {
+ result = this.mUsername.equals(other.mUsername) &&
+ this.mPasswd.equals(other.mPasswd) &&
+ this.mRealm.equals(other.mRealm) &&
+ this.mHomeSpFqdn.equals(other.mHomeSpFqdn);
+ }
+ if (this.mType.equals("TLS")) {
+ result = this.mRealm.equals(other.mRealm) &&
+ this.mHomeSpFqdn.equals(other.mHomeSpFqdn) &&
+ this.mClientCert.equals(other.mClientCert);
+ }
+ if (this.mType.equals("SIM")) {
+ result = this.mMcc.equals(other.mMcc) &&
+ this.mMnc.equals(other.mMnc) &&
+ this.mImsi.equals(other.mImsi) &&
+ this.mHomeSpFqdn.equals(other.mHomeSpFqdn);
+ }
+ }
+ }
+ return result;
+ }
+
+ @Override
+ /** @hide */
+ public String toString() {
+ StringBuffer sb = new StringBuffer();
+ String none = "<none>";
+
+ if (!DBG) {
+ sb.append(none);
+ } else {
+ sb.append(", UpdateIdentifier: ")
+ .append(mUpdateIdentifier == null ? none : mUpdateIdentifier)
+ .append(", SubscriptionUpdateMethod: ")
+ .append(mSubscriptionUpdateMethod == null ? none : mSubscriptionUpdateMethod)
+ .append(", Type: ").append(mType == null ? none : mType)
+ .append(", Username: ").append(mUsername == null ? none : mUsername)
+ .append(", Passwd: ").append(mPasswd == null ? none : mPasswd)
+ .append(", SubDMAccUsername: ")
+ .append(mSubscriptionUpdateUsername == null ? none : mSubscriptionUpdateUsername)
+ .append(", SubDMAccPassword: ")
+ .append(mSubscriptionUpdatePassword == null ? none : mSubscriptionUpdatePassword)
+ .append(", PolDMAccUsername: ")
+ .append(mPolicyUpdateUsername == null ? none : mPolicyUpdateUsername)
+ .append(", PolDMAccPassword: ")
+ .append(mPolicyUpdatePassword == null ? none : mPolicyUpdatePassword)
+ .append(", Imsi: ").append(mImsi == null ? none : mImsi)
+ .append(", Mcc: ").append(mMcc == null ? none : mMcc)
+ .append(", Mnc: ").append(mMnc == null ? none : mMnc)
+ .append(", CaRootCert: ").append(mCaRootCert == null ? none : mCaRootCert)
+ .append(", Realm: ").append(mRealm == null ? none : mRealm)
+ .append(", Priority: ").append(mCrednetialPriority)
+ .append(", Fqdn: ").append(mHomeSpFqdn == null ? none : mHomeSpFqdn)
+ .append(", Otherhomepartners: ")
+ .append(mOtherHomePartnerList == null ? none : mOtherHomePartnerList)
+ .append(", ExpirationDate: ")
+ .append(mExpirationDate == null ? none : mExpirationDate)
+ .append(", MaxBssLoad: ").append(mMaxBssLoad == null ? none : mMaxBssLoad)
+ .append(", SPExclusionList: ").append(mSpExclusionList);
+
+ if (mPreferredRoamingPartnerList != null) {
+ sb.append("PreferredRoamingPartnerList:");
+ for (WifiPasspointDmTree.PreferredRoamingPartnerList prpListItem : mPreferredRoamingPartnerList) {
+ sb.append("[fqdnmatch:").append(prpListItem.FQDN_Match).
+ append(", priority:").append(prpListItem.Priority).
+ append(", country:").append(prpListItem.Country).append("]");
+ }
+ }
+
+ if (mHomeOIList != null) {
+ sb.append("HomeOIList:");
+ for (WifiPasspointDmTree.HomeOIList HomeOIListItem : mHomeOIList) {
+ sb.append("[HomeOI:").append(HomeOIListItem.HomeOI).
+ append(", HomeOIRequired:").append(HomeOIListItem.HomeOIRequired).
+ append("]");
+ }
+ }
+
+ if (mMinBackhaulThresholdNetwork != null) {
+ sb.append("BackHaulThreshold:");
+ for (WifiPasspointDmTree.MinBackhaulThresholdNetwork BhtListItem : mMinBackhaulThresholdNetwork) {
+ sb.append("[networkType:").append(BhtListItem.NetworkType).
+ append(", dlBandwidth:").append(BhtListItem.DLBandwidth).
+ append(", ulBandwidth:").append(BhtListItem.ULBandwidth).
+ append("]");
+ }
+ }
+
+ if (mRequiredProtoPortTuple != null) {
+ sb.append("WifiMORequiredProtoPortTupleList:");
+ for (WifiPasspointDmTree.RequiredProtoPortTuple RpptListItem : mRequiredProtoPortTuple) {
+ sb.append("[IPProtocol:").append(RpptListItem.IPProtocol).
+ append(", PortNumber:").append(RpptListItem.PortNumber).
+ append("]");
+ }
+ }
+ }
+ return sb.toString();
+ }
+
+ /** Implement the Parcelable interface {@hide} */
+ public int describeContents() {
+ return 0;
+ }
+
+ /** Implement the Parcelable interface {@hide} */
+ public void writeToParcel(Parcel dest, int flags) {
+ dest.writeString(mWifiSpFqdn);
+ dest.writeString(mCredentialName);
+ dest.writeString(mType);
+ dest.writeInt(mCrednetialPriority);
+ dest.writeString(mHomeSpFqdn);
+ dest.writeString(mRealm);
+ }
+
+ /** Implement the Parcelable interface {@hide} */
+ public void readFromParcel(Parcel in) {
+ mWifiSpFqdn = in.readString();
+ mCredentialName = in.readString();
+ mType = in.readString();
+ mCrednetialPriority = in.readInt();
+ mHomeSpFqdn = in.readString();
+ mRealm = in.readString();
+ }
+
+ /** Implement the Parcelable interface {@hide} */
+ public static final Creator<WifiPasspointCredential> CREATOR =
+ new Creator<WifiPasspointCredential>() {
+ public WifiPasspointCredential createFromParcel(Parcel in) {
+ WifiPasspointCredential pc = new WifiPasspointCredential();
+ pc.mWifiSpFqdn = in.readString();
+ pc.mCredentialName = in.readString();
+ pc.mType = in.readString();
+ pc.mCrednetialPriority = in.readInt();
+ pc.mHomeSpFqdn = in.readString();
+ pc.mRealm = in.readString();
+ return pc;
+ }
+
+ public WifiPasspointCredential[] newArray(int size) {
+ return new WifiPasspointCredential[size];
+ }
+ };
+
+ /** @hide */
+ public int compareTo(WifiPasspointCredential another) {
+
+ //The smaller the higher
+ if (mCrednetialPriority < another.mCrednetialPriority) {
+ return -1;
+ } else if (mCrednetialPriority == another.mCrednetialPriority) {
+ return this.mType.compareTo(another.mType);
+ } else {
+ return 1;
+ }
+ }
+
+ @Override
+ /** @hide */
+ public int hashCode() {
+ int hash = 208;
+ if (mType != null) {
+ hash += mType.hashCode();
+ }
+ if (mRealm != null) {
+ hash += mRealm.hashCode();
+ }
+ if (mHomeSpFqdn != null) {
+ hash += mHomeSpFqdn.hashCode();
+ }
+ if (mUsername != null) {
+ hash += mUsername.hashCode();
+ }
+ if (mPasswd != null) {
+ hash += mPasswd.hashCode();
+ }
+
+ return hash;
+ }
+}
diff --git a/cmds/app_process/sigchain_proxy.cpp b/wifi/java/android/net/wifi/passpoint/WifiPasspointDmTree.aidl
similarity index 73%
copy from cmds/app_process/sigchain_proxy.cpp
copy to wifi/java/android/net/wifi/passpoint/WifiPasspointDmTree.aidl
index bb7a678..6a88b2e 100644
--- a/cmds/app_process/sigchain_proxy.cpp
+++ b/wifi/java/android/net/wifi/passpoint/WifiPasspointDmTree.aidl
@@ -1,11 +1,11 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
+/**
+ * Copyright (c) 2014, The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
- * http://www.apache.org/licenses/LICENSE-2.0
+ * 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,
@@ -14,4 +14,6 @@
* limitations under the License.
*/
-#include "sigchainlib/sigchain.cc"
+package android.net.wifi.passpoint;
+
+parcelable WifiPasspointDmTree;
diff --git a/wifi/java/android/net/wifi/passpoint/WifiPasspointDmTree.java b/wifi/java/android/net/wifi/passpoint/WifiPasspointDmTree.java
new file mode 100644
index 0000000..bbf5fc6
--- /dev/null
+++ b/wifi/java/android/net/wifi/passpoint/WifiPasspointDmTree.java
@@ -0,0 +1,1377 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net.wifi.passpoint;
+
+import android.os.Parcelable;
+import android.os.Parcel;
+import android.util.Log;
+
+import java.util.HashMap;
+
+/**
+ * Required Mobile Device Management Tree Structure
+ *
+ * +----------+
+ * | ./(Root) |
+ * +----+-----+
+ * |
+ * +---------+ | +---------+ +---------+
+ * | DevInfo |-----------+---------| Wi-Fi |--|SP FQDN* |
+ * +---------+ | +---------+ +---------+
+ * +---------+ | |
+ * |DevDetail|-----------+ +-----------------------+
+ * +---------+ |PerproviderSubscription|--<X>+
+ * +-----------------------+
+ *
+ * This class contains all nodes start from Wi-Fi
+ * @hide
+ **/
+public class WifiPasspointDmTree implements Parcelable {
+ private final static String TAG = "WifiTree";
+ public int PpsMoId;//plugfest used only
+ public HashMap<String, SpFqdn> spFqdn = new HashMap<String, SpFqdn>();//Maps.newHashMap();
+
+ public SpFqdn createSpFqdn(String name) {
+ SpFqdn obj = new SpFqdn(name);
+ spFqdn.put(name, obj);
+ return obj;
+ }
+
+ public static class SpFqdn implements Parcelable {
+ public String nodeName;
+ public PerProviderSubscription perProviderSubscription = new PerProviderSubscription();
+
+ public SpFqdn(String name) {
+ nodeName = name;
+ }
+
+ public SpFqdn() {
+ }
+
+ public SpFqdn(Parcel in) {
+ readFromParcel(in);
+ }
+
+ public int describeContents() {
+ return 0;
+ }
+
+ public void writeToParcel(Parcel out, int flags) {
+ out.writeString(nodeName);
+ out.writeParcelable(perProviderSubscription, flags);
+ }
+
+ public void readFromParcel(Parcel in) {
+ if (in == null) {
+ //log here
+ } else {
+ nodeName = in.readString();
+ perProviderSubscription = in.readParcelable(PerProviderSubscription.class
+ .getClassLoader());
+ }
+ }
+
+ public static final Parcelable.Creator<SpFqdn> CREATOR = new Parcelable.Creator<SpFqdn>() {
+ public SpFqdn createFromParcel(Parcel in) {
+ return new SpFqdn(in);
+ }
+
+ public SpFqdn[] newArray(int size) {
+ return new SpFqdn[size];
+ }
+ };
+ }
+
+ /**
+ * PerProviderSubscription
+ **/
+ public static class PerProviderSubscription implements Parcelable {
+ /**
+ * PerProviderSubscription/UpdateIdentifier
+ **/
+ public String UpdateIdentifier;
+ public HashMap<String, CredentialInfo> credentialInfo = new HashMap<String, CredentialInfo>();
+
+ public CredentialInfo createCredentialInfo(String name) {
+ CredentialInfo obj = new CredentialInfo(name);
+ credentialInfo.put(name, obj);
+ return obj;
+ }
+
+ public PerProviderSubscription() {
+ }
+
+ public PerProviderSubscription(Parcel in) {
+ readFromParcel(in);
+ }
+
+ public int describeContents() {
+ return 0;
+ }
+
+ public void writeToParcel(Parcel out, int flags) {
+ out.writeString(UpdateIdentifier);
+ out.writeMap(credentialInfo);
+ }
+
+ public void readFromParcel(Parcel in) {
+ if (in == null) {
+ //log here
+ } else {
+ UpdateIdentifier = in.readString();
+ in.readMap(credentialInfo, CredentialInfo.class.getClassLoader());
+ }
+ }
+
+ public static final Parcelable.Creator<PerProviderSubscription> CREATOR = new Parcelable.Creator<PerProviderSubscription>() {
+ public PerProviderSubscription createFromParcel(Parcel in) {
+ return new PerProviderSubscription(in);
+ }
+
+ public PerProviderSubscription[] newArray(int size) {
+ return new PerProviderSubscription[size];
+ }
+ };
+
+ }
+
+ /**
+ * PerProviderSubscription/<X+>
+ * This interior node contains the Home SP information, subscription policy, management and credential information.
+ **/
+ public static class CredentialInfo implements Parcelable {
+ public String nodeName;
+ public Policy policy = new Policy();
+ public String credentialPriority;
+ public HashMap<String, AAAServerTrustRoot> aAAServerTrustRoot = new HashMap<String, AAAServerTrustRoot>();
+ public SubscriptionUpdate subscriptionUpdate = new SubscriptionUpdate();
+ public HomeSP homeSP = new HomeSP();
+ public SubscriptionParameters subscriptionParameters = new SubscriptionParameters();
+ public Credential credential = new Credential();
+ public Extension extension = new Extension();
+
+ public CredentialInfo(String nn) {
+ nodeName = nn;
+ }
+
+ public AAAServerTrustRoot createAAAServerTrustRoot(String name, String url, String fp) {
+ AAAServerTrustRoot obj = new AAAServerTrustRoot(name, url, fp);
+ aAAServerTrustRoot.put(name, obj);
+ return obj;
+ }
+
+ public CredentialInfo() {
+ }
+
+ public CredentialInfo(Parcel in) {
+ readFromParcel(in);
+ }
+
+ public int describeContents() {
+ return 0;
+ }
+
+ public void writeToParcel(Parcel out, int flags) {
+ out.writeString(nodeName);
+ out.writeParcelable(policy, flags);
+ out.writeString(credentialPriority);
+ out.writeMap(aAAServerTrustRoot);
+ out.writeParcelable(subscriptionUpdate, flags);
+ out.writeParcelable(homeSP, flags);
+ out.writeParcelable(subscriptionParameters, flags);
+ out.writeParcelable(credential, flags);
+ //out.writeParcelable(extension, flags);
+ }
+
+ public void readFromParcel(Parcel in) {
+ if (in == null) {
+ //log here
+ } else {
+ nodeName = in.readString();
+ policy = in.readParcelable(Policy.class.getClassLoader());
+ credentialPriority = in.readString();
+ in.readMap(aAAServerTrustRoot, AAAServerTrustRoot.class.getClassLoader());
+ subscriptionUpdate = in.readParcelable(SubscriptionUpdate.class.getClassLoader());
+ homeSP = in.readParcelable(HomeSP.class.getClassLoader());
+ subscriptionParameters = in.readParcelable(SubscriptionParameters.class
+ .getClassLoader());
+ credential = in.readParcelable(Credential.class.getClassLoader());
+ //extension = in.readParcelable(Extension.class.getClassLoader());
+ }
+ }
+
+ public static final Parcelable.Creator<CredentialInfo> CREATOR = new Parcelable.Creator<CredentialInfo>() {
+ public CredentialInfo createFromParcel(Parcel in) {
+ return new CredentialInfo(in);
+ }
+
+ public CredentialInfo[] newArray(int size) {
+ return new CredentialInfo[size];
+ }
+ };
+
+ }
+
+ /**
+ * PerProviderSubscription/<X+>/Policy
+ **/
+ public static class Policy implements Parcelable {
+ public HashMap<String, PreferredRoamingPartnerList> preferredRoamingPartnerList = new HashMap<String, PreferredRoamingPartnerList>();
+ public HashMap<String, MinBackhaulThresholdNetwork> minBackhaulThreshold = new HashMap<String, MinBackhaulThresholdNetwork>();
+ public PolicyUpdate policyUpdate = new PolicyUpdate();
+ public HashMap<String, SPExclusionList> sPExclusionList = new HashMap<String, SPExclusionList>();
+ public HashMap<String, RequiredProtoPortTuple> requiredProtoPortTuple = new HashMap<String, RequiredProtoPortTuple>();
+ public String maximumBSSLoadValue;
+
+ public PreferredRoamingPartnerList createPreferredRoamingPartnerList(String name,
+ String fqdn, String priority, String country) {
+ PreferredRoamingPartnerList obj = new PreferredRoamingPartnerList(name, fqdn, priority,
+ country);
+ preferredRoamingPartnerList.put(name, obj);
+ return obj;
+ }
+
+ public MinBackhaulThresholdNetwork createMinBackhaulThreshold(String name, String type,
+ String dl, String ul) {
+ MinBackhaulThresholdNetwork obj = new MinBackhaulThresholdNetwork(name, type, dl, ul);
+ minBackhaulThreshold.put(name, obj);
+ return obj;
+ }
+
+ public SPExclusionList createSPExclusionList(String name, String ssid) {
+ SPExclusionList obj = new SPExclusionList(name, ssid);
+ sPExclusionList.put(name, obj);
+ return obj;
+ }
+
+ public RequiredProtoPortTuple createRequiredProtoPortTuple(String name, String proto,
+ String port) {
+ RequiredProtoPortTuple obj = new RequiredProtoPortTuple(name, proto, port);
+ requiredProtoPortTuple.put(name, obj);
+ return obj;
+ }
+
+ public Policy() {
+ }
+
+ public Policy(Parcel in) {
+ readFromParcel(in);
+ }
+
+ public int describeContents() {
+ return 0;
+ }
+
+ public void writeToParcel(Parcel out, int flags) {
+ out.writeMap(preferredRoamingPartnerList);
+ out.writeMap(minBackhaulThreshold);
+ out.writeParcelable(policyUpdate, flags);
+ out.writeMap(sPExclusionList);
+ out.writeMap(requiredProtoPortTuple);
+ out.writeString(maximumBSSLoadValue);
+ }
+
+ public void readFromParcel(Parcel in) {
+ if (in == null) {
+ //log here
+ } else {
+ in.readMap(preferredRoamingPartnerList,
+ PreferredRoamingPartnerList.class.getClassLoader());
+ in.readMap(minBackhaulThreshold, MinBackhaulThresholdNetwork.class.getClassLoader());
+ policyUpdate = in.readParcelable(PolicyUpdate.class.getClassLoader());
+ in.readMap(sPExclusionList, SPExclusionList.class.getClassLoader());
+ in.readMap(requiredProtoPortTuple, RequiredProtoPortTuple.class.getClassLoader());
+ maximumBSSLoadValue = in.readString();
+
+ }
+ }
+
+ public static final Parcelable.Creator<Policy> CREATOR = new Parcelable.Creator<Policy>() {
+ public Policy createFromParcel(Parcel in) {
+ return new Policy(in);
+ }
+
+ public Policy[] newArray(int size) {
+ return new Policy[size];
+ }
+ };
+
+ }
+
+ /**
+ * PerProviderSubscription/<X+>/Policy/PreferredRoamingPartnerList/<X+>
+ **/
+ public static class PreferredRoamingPartnerList implements Parcelable {
+ public String nodeName;
+ public String FQDN_Match; //maximum 255 + ",includeSubdomains", equals 273
+ public String Priority;
+ public String Country; // maximum 600 octets
+
+ public PreferredRoamingPartnerList(String nn, String f, String p, String c) {
+ nodeName = nn;
+ FQDN_Match = f;
+ Priority = p;
+ Country = c;
+ }
+
+ public PreferredRoamingPartnerList() {
+ }
+
+ public PreferredRoamingPartnerList(Parcel in) {
+ readFromParcel(in);
+ }
+
+ public int describeContents() {
+ return 0;
+ }
+
+ public void writeToParcel(Parcel out, int flags) {
+ out.writeString(nodeName);
+ out.writeString(FQDN_Match);
+ out.writeString(Priority);
+ out.writeString(Country);
+ }
+
+ public void readFromParcel(Parcel in) {
+ if (in == null) {
+ //log here
+ } else {
+ nodeName = in.readString();
+ FQDN_Match = in.readString();
+ Priority = in.readString();
+ Country = in.readString();
+ }
+ }
+
+ public static final Parcelable.Creator<PreferredRoamingPartnerList> CREATOR = new Parcelable.Creator<PreferredRoamingPartnerList>() {
+ public PreferredRoamingPartnerList createFromParcel(Parcel in) {
+ return new PreferredRoamingPartnerList(in);
+ }
+
+ public PreferredRoamingPartnerList[] newArray(int size) {
+ return new PreferredRoamingPartnerList[size];
+ }
+ };
+ }
+
+ /**
+ * PerProviderSubscription/<X+>/Policy/MinBackhaulThreshold
+ **/
+ public static class MinBackhaulThresholdNetwork implements Parcelable {
+ public String nodeName;
+ public String NetworkType;
+ public String DLBandwidth;
+ public String ULBandwidth;
+
+ public MinBackhaulThresholdNetwork(String nn, String nt, String d, String u) {
+ nodeName = nn;
+ NetworkType = nt;
+ DLBandwidth = d;
+ ULBandwidth = u;
+ }
+
+ public MinBackhaulThresholdNetwork() {
+ }
+
+ public MinBackhaulThresholdNetwork(Parcel in) {
+ readFromParcel(in);
+ }
+
+ public int describeContents() {
+ return 0;
+ }
+
+ public void writeToParcel(Parcel out, int flags) {
+ out.writeString(nodeName);
+ out.writeString(NetworkType);
+ out.writeString(DLBandwidth);
+ out.writeString(ULBandwidth);
+ }
+
+ public void readFromParcel(Parcel in) {
+ if (in == null) {
+ //log here
+ } else {
+ nodeName = in.readString();
+ NetworkType = in.readString();
+ DLBandwidth = in.readString();
+ ULBandwidth = in.readString();
+ }
+ }
+
+ public static final Parcelable.Creator<MinBackhaulThresholdNetwork> CREATOR = new Parcelable.Creator<MinBackhaulThresholdNetwork>() {
+ public MinBackhaulThresholdNetwork createFromParcel(Parcel in) {
+ return new MinBackhaulThresholdNetwork(in);
+ }
+
+ public MinBackhaulThresholdNetwork[] newArray(int size) {
+ return new MinBackhaulThresholdNetwork[size];
+ }
+ };
+
+ }
+
+ /**
+ * PerProviderSubscription/<X+>/Policy/PolicyUpdate
+ **/
+ public static class PolicyUpdate implements Parcelable {
+ public String UpdateInterval;
+ public String UpdateMethod;
+ public String Restriction;
+ public String URI;
+ public UsernamePassword usernamePassword = new UsernamePassword();
+ public String Other;
+ public TrustRoot trustRoot = new TrustRoot();
+
+ public PolicyUpdate() {
+ }
+
+ public PolicyUpdate(Parcel in) {
+ readFromParcel(in);
+ }
+
+ public int describeContents() {
+ return 0;
+ }
+
+ public void writeToParcel(Parcel out, int flags) {
+ out.writeString(UpdateInterval);
+ out.writeString(UpdateMethod);
+ out.writeString(Restriction);
+ out.writeString(URI);
+ out.writeParcelable(usernamePassword, flags);
+ out.writeString(Other);
+ out.writeParcelable(trustRoot, flags);
+
+ }
+
+ public void readFromParcel(Parcel in) {
+ if (in == null) {
+ //log here
+ } else {
+ UpdateInterval = in.readString();
+ UpdateMethod = in.readString();
+ Restriction = in.readString();
+ URI = in.readString();
+ usernamePassword = in.readParcelable(UsernamePassword.class.getClassLoader());
+ Other = in.readString();
+ trustRoot = in.readParcelable(TrustRoot.class.getClassLoader());
+ }
+ }
+
+ public static final Parcelable.Creator<PolicyUpdate> CREATOR = new Parcelable.Creator<PolicyUpdate>() {
+ public PolicyUpdate createFromParcel(Parcel in) {
+ return new PolicyUpdate(in);
+ }
+
+ public PolicyUpdate[] newArray(int size) {
+ return new PolicyUpdate[size];
+ }
+ };
+ }
+
+ /**
+ * PerProviderSubscription/<X+>/Policy/SPExclusionList
+ **/
+ public static class SPExclusionList implements Parcelable {
+ public String nodeName;
+ public String SSID;
+
+ public SPExclusionList(String nn, String s) {
+ nodeName = nn;
+ SSID = s;
+ }
+
+ public SPExclusionList() {
+ }
+
+ public SPExclusionList(Parcel in) {
+ readFromParcel(in);
+ }
+
+ public int describeContents() {
+ return 0;
+ }
+
+ public void writeToParcel(Parcel out, int flags) {
+ out.writeString(nodeName);
+ out.writeString(SSID);
+ }
+
+ public void readFromParcel(Parcel in) {
+ if (in == null) {
+ //log here
+ } else {
+ nodeName = in.readString();
+ SSID = in.readString();
+ }
+ }
+
+ public static final Parcelable.Creator<SPExclusionList> CREATOR = new Parcelable.Creator<SPExclusionList>() {
+ public SPExclusionList createFromParcel(Parcel in) {
+ return new SPExclusionList(in);
+ }
+
+ public SPExclusionList[] newArray(int size) {
+ return new SPExclusionList[size];
+ }
+ };
+ }
+
+ /**
+ * PerProviderSubscription/<X+>/Policy/RequiredProtoPortTuple
+ **/
+ public static class RequiredProtoPortTuple implements Parcelable {
+ public String nodeName;
+ public String IPProtocol;
+ public String PortNumber;
+
+ public RequiredProtoPortTuple() {
+ }
+
+ public RequiredProtoPortTuple(String nn, String protocol, String port) {
+ nodeName = nn;
+ IPProtocol = protocol;
+ PortNumber = port;
+ }
+
+ public RequiredProtoPortTuple(Parcel in) {
+ readFromParcel(in);
+ }
+
+ public int describeContents() {
+ return 0;
+ }
+
+ public void writeToParcel(Parcel out, int flags) {
+ out.writeString(nodeName);
+ out.writeString(IPProtocol);
+ out.writeString(PortNumber);
+ }
+
+ public void readFromParcel(Parcel in) {
+ if (in == null) {
+ //log here
+ } else {
+ nodeName = in.readString();
+ IPProtocol = in.readString();
+ PortNumber = in.readString();
+ }
+ }
+
+ public static final Parcelable.Creator<RequiredProtoPortTuple> CREATOR = new Parcelable.Creator<RequiredProtoPortTuple>() {
+ public RequiredProtoPortTuple createFromParcel(Parcel in) {
+ return new RequiredProtoPortTuple(in);
+ }
+
+ public RequiredProtoPortTuple[] newArray(int size) {
+ return new RequiredProtoPortTuple[size];
+ }
+ };
+ }
+
+ /**
+ * PerProviderSubscription/<X+>/AAAServerTrustRoot
+ **/
+ public static class AAAServerTrustRoot implements Parcelable {
+ public String nodeName;
+ public String CertURL;
+ public String CertSHA256Fingerprint;
+
+ public AAAServerTrustRoot(String nn, String url, String fp) {
+ nodeName = nn;
+ CertURL = url;
+ CertSHA256Fingerprint = fp;
+ }
+
+ public AAAServerTrustRoot() {
+ }
+
+ public AAAServerTrustRoot(Parcel in) {
+ readFromParcel(in);
+ }
+
+ public int describeContents() {
+ return 0;
+ }
+
+ public void writeToParcel(Parcel out, int flags) {
+ out.writeString(nodeName);
+ out.writeString(CertURL);
+ out.writeString(CertSHA256Fingerprint);
+ }
+
+ public void readFromParcel(Parcel in) {
+ if (in == null) {
+ //log here
+ } else {
+ nodeName = in.readString();
+ CertURL = in.readString();
+ CertSHA256Fingerprint = in.readString();
+ }
+ }
+
+ public static final Parcelable.Creator<AAAServerTrustRoot> CREATOR = new Parcelable.Creator<AAAServerTrustRoot>() {
+ public AAAServerTrustRoot createFromParcel(Parcel in) {
+ return new AAAServerTrustRoot(in);
+ }
+
+ public AAAServerTrustRoot[] newArray(int size) {
+ return new AAAServerTrustRoot[size];
+ }
+ };
+ }
+
+ /**
+ * PerProviderSubscription/<X+>/SubscriptionUpdate
+ **/
+ public static class SubscriptionUpdate implements Parcelable {
+ public String UpdateInterval;
+ public String UpdateMethod;
+ public String Restriction;
+ public String URI;
+ public UsernamePassword usernamePassword = new UsernamePassword();
+ public String Other;
+ public TrustRoot trustRoot = new TrustRoot();
+
+ public SubscriptionUpdate() {
+ }
+
+ public SubscriptionUpdate(Parcel in) {
+ readFromParcel(in);
+ }
+
+ public int describeContents() {
+ return 0;
+ }
+
+ public void writeToParcel(Parcel out, int flags) {
+ out.writeString(UpdateInterval);
+ out.writeString(UpdateMethod);
+ out.writeString(Restriction);
+ out.writeString(URI);
+ out.writeParcelable(usernamePassword, flags);
+ out.writeString(Other);
+ out.writeParcelable(trustRoot, flags);
+ }
+
+ public void readFromParcel(Parcel in) {
+ if (in == null) {
+ //log here
+ } else {
+ UpdateInterval = in.readString();
+ UpdateMethod = in.readString();
+ Restriction = in.readString();
+ URI = in.readString();
+ usernamePassword = in.readParcelable(UsernamePassword.class.getClassLoader());
+ Other = in.readString();
+ trustRoot = in.readParcelable(TrustRoot.class.getClassLoader());
+ }
+ }
+
+ public static final Parcelable.Creator<SubscriptionUpdate> CREATOR = new Parcelable.Creator<SubscriptionUpdate>() {
+ public SubscriptionUpdate createFromParcel(Parcel in) {
+ return new SubscriptionUpdate(in);
+ }
+
+ public SubscriptionUpdate[] newArray(int size) {
+ return new SubscriptionUpdate[size];
+ }
+ };
+
+ }
+
+ /**
+ * PerProviderSubscription/<X+>/Policy/PolicyUpdate/TrustRoot
+ * PerProviderSubscription/<X+>/SubscriptionUpdate/TrustRoot
+ * PerProviderSubscription/<X+>/AAAServerTrustRoot/<X+>
+ **/
+ public static class TrustRoot implements Parcelable {
+ public String CertURL;
+ public String CertSHA256Fingerprint;
+
+ public TrustRoot() {
+ }
+
+ public TrustRoot(Parcel in) {
+ readFromParcel(in);
+ }
+
+ public int describeContents() {
+ return 0;
+ }
+
+ public void writeToParcel(Parcel out, int flags) {
+ out.writeString(CertURL);
+ out.writeString(CertSHA256Fingerprint);
+ }
+
+ public void readFromParcel(Parcel in) {
+ if (in == null) {
+ //log here
+ } else {
+ CertURL = in.readString();
+ CertSHA256Fingerprint = in.readString();
+ }
+ }
+
+ public static final Parcelable.Creator<TrustRoot> CREATOR = new Parcelable.Creator<TrustRoot>() {
+ public TrustRoot createFromParcel(Parcel in) {
+ return new TrustRoot(in);
+ }
+
+ public TrustRoot[] newArray(int size) {
+ return new TrustRoot[size];
+ }
+ };
+ }
+
+ /**
+ * PerProviderSubscription/<X+>/Policy/PolicyUpdate/UsernamePassword
+ * PerProviderSubscription/<X+>/SubscriptionUpdate/UsernamePassword
+ * PerProviderSubscription/<X+>/Credential/UsernamePassword
+ **/
+ public static class UsernamePassword implements Parcelable {
+ public String Username;
+ public String Password;
+ //following are Credential node used only
+ public boolean MachineManaged;
+ public String SoftTokenApp;
+ public String AbleToShare;
+ public EAPMethod eAPMethod = new EAPMethod();
+
+ public UsernamePassword() {
+ }
+
+ public UsernamePassword(Parcel in) {
+ readFromParcel(in);
+ }
+
+ public int describeContents() {
+ return 0;
+ }
+
+ public void writeToParcel(Parcel out, int flags) {
+ out.writeString(Username);
+ out.writeString(Password);
+ out.writeInt(MachineManaged ? 1 : 0);
+ out.writeString(SoftTokenApp);
+ out.writeString(AbleToShare);
+ out.writeParcelable(eAPMethod, flags);
+ }
+
+ public void readFromParcel(Parcel in) {
+ if (in == null) {
+ //log here
+ } else {
+ Username = in.readString();
+ Password = in.readString();
+ MachineManaged = (in.readInt() == 1) ? true : false;
+ SoftTokenApp = in.readString();
+ AbleToShare = in.readString();
+ eAPMethod = in.readParcelable(EAPMethod.class.getClassLoader());
+ }
+ }
+
+ public static final Parcelable.Creator<UsernamePassword> CREATOR = new Parcelable.Creator<UsernamePassword>() {
+ public UsernamePassword createFromParcel(Parcel in) {
+ return new UsernamePassword(in);
+ }
+
+ public UsernamePassword[] newArray(int size) {
+ return new UsernamePassword[size];
+ }
+ };
+
+ }
+
+ /**
+ * PerProviderSubscription/<X+>/Credential/UsernamePassword/EAPMethod
+ **/
+ public static class EAPMethod implements Parcelable {
+ public String EAPType;
+ public String VendorId;
+ public String VendorType;
+ public String InnerEAPType;
+ public String InnerVendorId;
+ public String InnerVendorType;
+ public String InnerMethod;
+
+ public EAPMethod() {
+ }
+
+ public EAPMethod(Parcel in) {
+ readFromParcel(in);
+ }
+
+ public int describeContents() {
+ return 0;
+ }
+
+ public void writeToParcel(Parcel out, int flags) {
+ out.writeString(EAPType);
+ out.writeString(VendorId);
+ out.writeString(VendorType);
+ out.writeString(InnerEAPType);
+ out.writeString(InnerVendorId);
+ out.writeString(InnerVendorType);
+ out.writeString(InnerMethod);
+ }
+
+ public void readFromParcel(Parcel in) {
+ if (in == null) {
+ //log here
+ } else {
+ EAPType = in.readString();
+ VendorId = in.readString();
+ VendorType = in.readString();
+ InnerEAPType = in.readString();
+ InnerVendorId = in.readString();
+ InnerVendorType = in.readString();
+ InnerMethod = in.readString();
+ }
+ }
+
+ public static final Parcelable.Creator<EAPMethod> CREATOR = new Parcelable.Creator<EAPMethod>() {
+ public EAPMethod createFromParcel(Parcel in) {
+ return new EAPMethod(in);
+ }
+
+ public EAPMethod[] newArray(int size) {
+ return new EAPMethod[size];
+ }
+ };
+ }
+
+ /**
+ * PerProviderSubscription/<X+>/HomeSP
+ **/
+ public static class HomeSP implements Parcelable {
+ public HashMap<String, NetworkID> networkID = new HashMap<String, NetworkID>();
+ public String FriendlyName;
+ public String IconURL;
+ public String FQDN;
+ public HashMap<String, HomeOIList> homeOIList = new HashMap<String, HomeOIList>();
+ public HashMap<String, OtherHomePartners> otherHomePartners = new HashMap<String, OtherHomePartners>();
+ public String RoamingConsortiumOI;
+
+ public NetworkID createNetworkID(String name, String ssid, String hessid) {
+ NetworkID obj = new NetworkID(name, ssid, hessid);
+ networkID.put(name, obj);
+ return obj;
+ }
+
+ public HomeOIList createHomeOIList(String name, String homeoi, boolean required) {
+ HomeOIList obj = new HomeOIList(name, homeoi, required);
+ homeOIList.put(name, obj);
+ return obj;
+ }
+
+ public OtherHomePartners createOtherHomePartners(String name, String fqdn) {
+ OtherHomePartners obj = new OtherHomePartners(name, fqdn);
+ otherHomePartners.put(name, obj);
+ return obj;
+ }
+
+ public HomeSP() {
+ }
+
+ public HomeSP(Parcel in) {
+ readFromParcel(in);
+ }
+
+ public int describeContents() {
+ return 0;
+ }
+
+ public void writeToParcel(Parcel out, int flags) {
+ out.writeMap(networkID);
+ out.writeString(FriendlyName);
+ out.writeString(IconURL);
+ out.writeString(FQDN);
+ out.writeMap(homeOIList);
+ out.writeMap(otherHomePartners);
+ out.writeString(RoamingConsortiumOI);
+ }
+
+ public void readFromParcel(Parcel in) {
+ if (in == null) {
+ //log here
+ } else {
+ in.readMap(networkID, NetworkID.class.getClassLoader());
+ FriendlyName = in.readString();
+ IconURL = in.readString();
+ FQDN = in.readString();
+ in.readMap(homeOIList, HomeOIList.class.getClassLoader());
+ in.readMap(otherHomePartners, OtherHomePartners.class.getClassLoader());
+ RoamingConsortiumOI = in.readString();
+ }
+ }
+
+ public static final Parcelable.Creator<HomeSP> CREATOR = new Parcelable.Creator<HomeSP>() {
+ public HomeSP createFromParcel(Parcel in) {
+ return new HomeSP(in);
+ }
+
+ public HomeSP[] newArray(int size) {
+ return new HomeSP[size];
+ }
+ };
+
+ }
+
+ /**
+ * PerProviderSubscription/<X+>/HomeSP/NetworkID
+ **/
+ public static class NetworkID implements Parcelable {
+ public String nodeName;
+ public String SSID;
+ public String HESSID;
+
+ public NetworkID(String nn, String s, String h) {
+ nodeName = nn;
+ SSID = s;
+ HESSID = h;
+ }
+
+ public NetworkID() {
+ }
+
+ public NetworkID(Parcel in) {
+ readFromParcel(in);
+ }
+
+ public int describeContents() {
+ return 0;
+ }
+
+ public void writeToParcel(Parcel out, int flags) {
+ out.writeString(nodeName);
+ out.writeString(SSID);
+ out.writeString(HESSID);
+ }
+
+ public void readFromParcel(Parcel in) {
+ if (in == null) {
+ //log here
+ } else {
+ nodeName = in.readString();
+ SSID = in.readString();
+ HESSID = in.readString();
+ }
+ }
+
+ public static final Parcelable.Creator<NetworkID> CREATOR = new Parcelable.Creator<NetworkID>() {
+ public NetworkID createFromParcel(Parcel in) {
+ return new NetworkID(in);
+ }
+
+ public NetworkID[] newArray(int size) {
+ return new NetworkID[size];
+ }
+ };
+
+ }
+
+ /**
+ * PerProviderSubscription/<X+>/HomeSP/HomeOIList
+ **/
+ public static class HomeOIList implements Parcelable {
+ public String nodeName;
+ public String HomeOI;
+ public boolean HomeOIRequired;
+
+ public HomeOIList(String nn, String h, boolean r) {
+ nodeName = nn;
+ HomeOI = h;
+ HomeOIRequired = r;
+ }
+
+ public HomeOIList() {
+ }
+
+ public HomeOIList(Parcel in) {
+ readFromParcel(in);
+ }
+
+ public int describeContents() {
+ return 0;
+ }
+
+ public void writeToParcel(Parcel out, int flags) {
+ out.writeString(nodeName);
+ out.writeString(HomeOI);
+ out.writeInt(HomeOIRequired ? 1 : 0);
+ }
+
+ public void readFromParcel(Parcel in) {
+ if (in == null) {
+ //log here
+ } else {
+ nodeName = in.readString();
+ HomeOI = in.readString();
+ HomeOIRequired = (in.readInt() == 1) ? true : false;
+ }
+ }
+
+ public static final Parcelable.Creator<HomeOIList> CREATOR = new Parcelable.Creator<HomeOIList>() {
+ public HomeOIList createFromParcel(Parcel in) {
+ return new HomeOIList(in);
+ }
+
+ public HomeOIList[] newArray(int size) {
+ return new HomeOIList[size];
+ }
+ };
+
+ }
+
+ /**
+ * PerProviderSubscription/<X+>/HomeSP/OtherHomePartners
+ **/
+ public static class OtherHomePartners implements Parcelable {
+ public String nodeName;
+ public String FQDN;
+
+ public OtherHomePartners(String nn, String f) {
+ nodeName = nn;
+ FQDN = f;
+ }
+
+ public OtherHomePartners() {
+ }
+
+ public OtherHomePartners(Parcel in) {
+ readFromParcel(in);
+ }
+
+ public int describeContents() {
+ return 0;
+ }
+
+ public void writeToParcel(Parcel out, int flags) {
+ out.writeString(nodeName);
+ out.writeString(FQDN);
+ }
+
+ public void readFromParcel(Parcel in) {
+ if (in == null) {
+ //log here
+ } else {
+ nodeName = in.readString();
+ FQDN = in.readString();
+ }
+ }
+
+ public static final Parcelable.Creator<OtherHomePartners> CREATOR = new Parcelable.Creator<OtherHomePartners>() {
+ public OtherHomePartners createFromParcel(Parcel in) {
+ return new OtherHomePartners(in);
+ }
+
+ public OtherHomePartners[] newArray(int size) {
+ return new OtherHomePartners[size];
+ }
+ };
+
+ }
+
+ /**
+ * PerProviderSubscription/<X+>/SubscriptionParameters
+ **/
+ public static class SubscriptionParameters implements Parcelable {
+ public String CreationDate;
+ public String ExpirationDate;
+ public String TypeOfSubscription;
+ public UsageLimits usageLimits = new UsageLimits();
+
+ public SubscriptionParameters() {
+ }
+
+ public SubscriptionParameters(Parcel in) {
+ readFromParcel(in);
+ }
+
+ public int describeContents() {
+ return 0;
+ }
+
+ public void writeToParcel(Parcel out, int flags) {
+ out.writeString(CreationDate);
+ out.writeString(ExpirationDate);
+ out.writeString(TypeOfSubscription);
+ out.writeParcelable(usageLimits, flags);
+ }
+
+ public void readFromParcel(Parcel in) {
+ if (in == null) {
+ //log here
+ } else {
+ CreationDate = in.readString();
+ ExpirationDate = in.readString();
+ TypeOfSubscription = in.readString();
+ usageLimits = in.readParcelable(UsageLimits.class.getClassLoader());
+ }
+ }
+
+ public static final Parcelable.Creator<SubscriptionParameters> CREATOR = new Parcelable.Creator<SubscriptionParameters>() {
+ public SubscriptionParameters createFromParcel(Parcel in) {
+ return new SubscriptionParameters(in);
+ }
+
+ public SubscriptionParameters[] newArray(int size) {
+ return new SubscriptionParameters[size];
+ }
+ };
+
+ }
+
+ /**
+ * PerProviderSubscription/<X+>/SubscriptionParameters/UsageLimits
+ **/
+ public static class UsageLimits implements Parcelable {
+ public String DataLimit;
+ public String StartDate;
+ public String TimeLimit;
+ public String UsageTimePeriod;
+
+ public UsageLimits() {
+ }
+
+ public UsageLimits(Parcel in) {
+ readFromParcel(in);
+ }
+
+ public int describeContents() {
+ return 0;
+ }
+
+ public void writeToParcel(Parcel out, int flags) {
+ out.writeString(DataLimit);
+ out.writeString(StartDate);
+ out.writeString(TimeLimit);
+ out.writeString(UsageTimePeriod);
+ }
+
+ public void readFromParcel(Parcel in) {
+ if (in == null) {
+ //log here
+ } else {
+ DataLimit = in.readString();
+ StartDate = in.readString();
+ TimeLimit = in.readString();
+ UsageTimePeriod = in.readString();
+ }
+ }
+
+ public static final Parcelable.Creator<UsageLimits> CREATOR = new Parcelable.Creator<UsageLimits>() {
+ public UsageLimits createFromParcel(Parcel in) {
+ return new UsageLimits(in);
+ }
+
+ public UsageLimits[] newArray(int size) {
+ return new UsageLimits[size];
+ }
+ };
+ }
+
+ /**
+ * PerProviderSubscription/<X+>/Credential
+ **/
+ public static class Credential implements Parcelable {
+ public String CreationDate;
+ public String ExpirationDate;
+ public UsernamePassword usernamePassword = new UsernamePassword();
+ public DigitalCertificate digitalCertificate = new DigitalCertificate();
+ public String Realm;
+ public boolean CheckAAAServerCertStatus;
+ public SIM sim = new SIM();
+
+ public Credential() {
+ }
+
+ public Credential(Parcel in) {
+ readFromParcel(in);
+ }
+
+ public int describeContents() {
+ return 0;
+ }
+
+ public void writeToParcel(Parcel out, int flags) {
+ out.writeString(CreationDate);
+ out.writeString(ExpirationDate);
+ out.writeParcelable(usernamePassword, flags);
+ out.writeParcelable(digitalCertificate, flags);
+ out.writeString(Realm);
+ out.writeInt(CheckAAAServerCertStatus ? 1 : 0);
+ out.writeParcelable(sim, flags);
+ }
+
+ public void readFromParcel(Parcel in) {
+ if (in == null) {
+ //log here
+ } else {
+ CreationDate = in.readString();
+ ExpirationDate = in.readString();
+ usernamePassword = in.readParcelable(UsernamePassword.class.getClassLoader());
+ digitalCertificate = in.readParcelable(DigitalCertificate.class.getClassLoader());
+ Realm = in.readString();
+ CheckAAAServerCertStatus = (in.readInt() == 1) ? true : false;
+ sim = in.readParcelable(SIM.class.getClassLoader());
+ }
+ }
+
+ public static final Parcelable.Creator<Credential> CREATOR = new Parcelable.Creator<Credential>() {
+ public Credential createFromParcel(Parcel in) {
+ return new Credential(in);
+ }
+
+ public Credential[] newArray(int size) {
+ return new Credential[size];
+ }
+ };
+ }
+
+ /**
+ * PerProviderSubscription/<X+>/Credential/DigitalCertificate
+ **/
+ public static class DigitalCertificate implements Parcelable {
+ public String CertificateType;
+ public String CertSHA256Fingerprint;
+
+ public DigitalCertificate() {
+ }
+
+ public DigitalCertificate(Parcel in) {
+ readFromParcel(in);
+ }
+
+ public int describeContents() {
+ return 0;
+ }
+
+ public void writeToParcel(Parcel out, int flags) {
+ out.writeString(CertificateType);
+ out.writeString(CertSHA256Fingerprint);
+ }
+
+ public void readFromParcel(Parcel in) {
+ if (in == null) {
+ //log here
+ } else {
+ CertificateType = in.readString();
+ CertSHA256Fingerprint = in.readString();
+ }
+ }
+
+ public static final Parcelable.Creator<DigitalCertificate> CREATOR = new Parcelable.Creator<DigitalCertificate>() {
+ public DigitalCertificate createFromParcel(Parcel in) {
+ return new DigitalCertificate(in);
+ }
+
+ public DigitalCertificate[] newArray(int size) {
+ return new DigitalCertificate[size];
+ }
+ };
+
+ }
+
+ /**
+ * PerProviderSubscription/<X+>/Credential/SIM
+ **/
+ public static class SIM implements Parcelable {
+ public String IMSI;
+ public String EAPType;
+
+ public SIM() {
+ }
+
+ public SIM(Parcel in) {
+ readFromParcel(in);
+ }
+
+ public int describeContents() {
+ return 0;
+ }
+
+ public void writeToParcel(Parcel out, int flags) {
+ out.writeString(IMSI);
+ out.writeString(EAPType);
+ }
+
+ public void readFromParcel(Parcel in) {
+ if (in == null) {
+ //log here
+ } else {
+ IMSI = in.readString();
+ EAPType = in.readString();
+ }
+ }
+
+ public static final Parcelable.Creator<SIM> CREATOR = new Parcelable.Creator<SIM>() {
+ public SIM createFromParcel(Parcel in) {
+ return new SIM(in);
+ }
+
+ public SIM[] newArray(int size) {
+ return new SIM[size];
+ }
+ };
+
+ }
+
+ /**
+ * PerProviderSubscription/<X+>/Extension
+ **/
+ public static class Extension {
+ public String empty;
+ }
+
+ public WifiPasspointDmTree() {
+ }
+
+ public WifiPasspointDmTree(Parcel in) {
+ readFromParcel(in);
+ }
+
+ public int describeContents() {
+ return 0;
+ }
+
+ public void writeToParcel(Parcel out, int flags) {
+ out.writeMap(spFqdn);
+ }
+
+ public void readFromParcel(Parcel in) {
+ if (in == null) {
+ //log here
+ } else {
+ in.readMap(spFqdn, SpFqdn.class.getClassLoader());
+ }
+ }
+
+ public static final Parcelable.Creator<WifiPasspointDmTree> CREATOR = new Parcelable.Creator<WifiPasspointDmTree>() {
+ public WifiPasspointDmTree createFromParcel(Parcel in) {
+ return new WifiPasspointDmTree(in);
+ }
+
+ public WifiPasspointDmTree[] newArray(int size) {
+ return new WifiPasspointDmTree[size];
+ }
+ };
+
+}
diff --git a/cmds/app_process/sigchain_proxy.cpp b/wifi/java/android/net/wifi/passpoint/WifiPasspointInfo.aidl
similarity index 73%
copy from cmds/app_process/sigchain_proxy.cpp
copy to wifi/java/android/net/wifi/passpoint/WifiPasspointInfo.aidl
index bb7a678..27f23bc 100644
--- a/cmds/app_process/sigchain_proxy.cpp
+++ b/wifi/java/android/net/wifi/passpoint/WifiPasspointInfo.aidl
@@ -1,11 +1,11 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
+/**
+ * Copyright (c) 2014, The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
- * http://www.apache.org/licenses/LICENSE-2.0
+ * 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,
@@ -14,4 +14,6 @@
* limitations under the License.
*/
-#include "sigchainlib/sigchain.cc"
+package android.net.wifi.passpoint;
+
+parcelable WifiPasspointInfo;
diff --git a/wifi/java/android/net/wifi/passpoint/WifiPasspointInfo.java b/wifi/java/android/net/wifi/passpoint/WifiPasspointInfo.java
new file mode 100644
index 0000000..33db3f5
--- /dev/null
+++ b/wifi/java/android/net/wifi/passpoint/WifiPasspointInfo.java
@@ -0,0 +1,559 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net.wifi.passpoint;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/** @hide */
+public class WifiPasspointInfo implements Parcelable {
+
+ /** TODO doc */
+ public static final int ANQP_CAPABILITY = 1 << 0;
+
+ /** TODO doc */
+ public static final int VENUE_NAME = 1 << 1;
+
+ /** TODO doc */
+ public static final int NETWORK_AUTH_TYPE = 1 << 2;
+
+ /** TODO doc */
+ public static final int ROAMING_CONSORTIUM = 1 << 3;
+
+ /** TODO doc */
+ public static final int IP_ADDR_TYPE_AVAILABILITY = 1 << 4;
+
+ /** TODO doc */
+ public static final int NAI_REALM = 1 << 5;
+
+ /** TODO doc */
+ public static final int CELLULAR_NETWORK = 1 << 6;
+
+ /** TODO doc */
+ public static final int DOMAIN_NAME = 1 << 7;
+
+ /** TODO doc */
+ public static final int HOTSPOT_CAPABILITY = 1 << 8;
+
+ /** TODO doc */
+ public static final int OPERATOR_FRIENDLY_NAME = 1 << 9;
+
+ /** TODO doc */
+ public static final int WAN_METRICS = 1 << 10;
+
+ /** TODO doc */
+ public static final int CONNECTION_CAPABILITY = 1 << 11;
+
+ /** TODO doc */
+ public static final int OSU_PROVIDER = 1 << 12;
+
+ /** TODO doc */
+ public static final int PRESET_CRED_MATCH =
+ ANQP_CAPABILITY |
+ HOTSPOT_CAPABILITY |
+ NAI_REALM |
+ CELLULAR_NETWORK |
+ DOMAIN_NAME;
+
+ /** TODO doc */
+ public static final int PRESET_ALL =
+ ANQP_CAPABILITY |
+ VENUE_NAME |
+ NETWORK_AUTH_TYPE |
+ ROAMING_CONSORTIUM |
+ IP_ADDR_TYPE_AVAILABILITY |
+ NAI_REALM |
+ CELLULAR_NETWORK |
+ DOMAIN_NAME |
+ HOTSPOT_CAPABILITY |
+ OPERATOR_FRIENDLY_NAME |
+ WAN_METRICS |
+ CONNECTION_CAPABILITY |
+ OSU_PROVIDER;
+
+
+ public static class WanMetrics {
+ public static final int STATUS_RESERVED = 0;
+ public static final int STATUS_UP = 1;
+ public static final int STATUS_DOWN = 2;
+ public static final int STATUS_TEST = 3;
+
+ public int wanInfo;
+ public long downlinkSpeed;
+ public long uplinkSpeed;
+ public int downlinkLoad;
+ public int uplinkLoad;
+ public int lmd;
+
+ public int getLinkStatus() {
+ return wanInfo & 0x3;
+ }
+
+ public boolean getSymmetricLink() {
+ return (wanInfo & (1 << 2)) != 0;
+ }
+
+ public boolean getAtCapacity() {
+ return (wanInfo & (1 << 3)) != 0;
+ }
+
+ @Override
+ public String toString() {
+ return wanInfo + "," + downlinkSpeed + "," + uplinkSpeed + "," +
+ downlinkLoad + "," + uplinkLoad + "," + lmd;
+ }
+ }
+
+ public static class IpProtoPort {
+ public static final int STATUS_CLOSED = 0;
+ public static final int STATUS_OPEN = 1;
+ public static final int STATUS_UNKNOWN = 2;
+
+ public int proto;
+ public int port;
+ public int status;
+
+ @Override
+ public String toString() {
+ return proto + "," + port + "," + status;
+ }
+ }
+
+ public static class NetworkAuthType {
+ public static final int TYPE_TERMS_AND_CONDITION = 0;
+ public static final int TYPE_ONLINE_ENROLLMENT = 1;
+ public static final int TYPE_HTTP_REDIRECTION = 2;
+ public static final int TYPE_DNS_REDIRECTION = 3;
+
+ public int type;
+ public String redirectUrl;
+
+ @Override
+ public String toString() {
+ return type + "," + redirectUrl;
+ }
+ }
+
+ public static class IpAddressType {
+ public static final int IPV6_NOT_AVAILABLE = 0;
+ public static final int IPV6_AVAILABLE = 1;
+ public static final int IPV6_UNKNOWN = 2;
+
+ public static final int IPV4_NOT_AVAILABLE = 0;
+ public static final int IPV4_PUBLIC = 1;
+ public static final int IPV4_PORT_RESTRICTED = 2;
+ public static final int IPV4_SINGLE_NAT = 3;
+ public static final int IPV4_DOUBLE_NAT = 4;
+ public static final int IPV4_PORT_RESTRICTED_SINGLE_NAT = 5;
+ public static final int IPV4_PORT_RESTRICTED_DOUBLE_NAT = 6;
+ public static final int IPV4_PORT_UNKNOWN = 7;
+
+ private static final int NULL_VALUE = -1;
+
+ public int availability;
+
+ public int getIpv6Availability() {
+ return availability & 0x3;
+ }
+
+ public int getIpv4Availability() {
+ return (availability & 0xFF) >> 2;
+ }
+
+ @Override
+ public String toString() {
+ return getIpv6Availability() + "," + getIpv4Availability();
+ }
+ }
+
+ public static class NaiRealm {
+ public static final int ENCODING_RFC4282 = 0;
+ public static final int ENCODING_UTF8 = 1;
+
+ public int encoding;
+ public String realm;
+
+ @Override
+ public String toString() {
+ return encoding + "," + realm;
+ }
+ }
+
+ public static class CellularNetwork {
+ public String mcc;
+ public String mnc;
+
+ @Override
+ public String toString() {
+ return mcc + "," + mnc;
+ }
+ }
+
+ /** BSSID */
+ public String bssid;
+
+ /** venue name */
+ public String venueName;
+
+ /** list of network authentication types */
+ public List<NetworkAuthType> networkAuthTypeList;
+
+ /** list of roaming consortium OIs */
+ public List<String> roamingConsortiumList;
+
+ /** IP address availability */
+ public IpAddressType ipAddrTypeAvailability;
+
+ /** list of NAI realm */
+ public List<NaiRealm> naiRealmList;
+
+ /** list of 3GPP cellular network */
+ public List<CellularNetwork> cellularNetworkList;
+
+ /** list of fully qualified domain name (FQDN) */
+ public List<String> domainNameList;
+
+ /** HS 2.0 operator friendly name */
+ public String operatorFriendlyName;
+
+ /** HS 2.0 wan metrics */
+ public WanMetrics wanMetrics;
+
+ /** list of HS 2.0 IP proto port */
+ public List<IpProtoPort> connectionCapabilityList;
+
+ /** list of HS 2.0 OSU providers */
+ public List<WifiPasspointOsuProvider> osuProviderList;
+
+ /**
+ * Convert mask to ANQP subtypes, for supplicant command use.
+ *
+ * @param mask The ANQP subtypes mask.
+ * @return String of ANQP subtypes, good for supplicant command use
+ * @hide
+ */
+ public static String toAnqpSubtypes(int mask) {
+ StringBuilder sb = new StringBuilder();
+ if ((mask & ANQP_CAPABILITY) != 0)
+ sb.append("257,");
+ if ((mask & VENUE_NAME) != 0)
+ sb.append("258,");
+ if ((mask & NETWORK_AUTH_TYPE) != 0)
+ sb.append("260,");
+ if ((mask & ROAMING_CONSORTIUM) != 0)
+ sb.append("261,");
+ if ((mask & IP_ADDR_TYPE_AVAILABILITY) != 0)
+ sb.append("262,");
+ if ((mask & NAI_REALM) != 0)
+ sb.append("263,");
+ if ((mask & CELLULAR_NETWORK) != 0)
+ sb.append("264,");
+ if ((mask & DOMAIN_NAME) != 0)
+ sb.append("268,");
+ if ((mask & HOTSPOT_CAPABILITY) != 0)
+ sb.append("hs20:2,");
+ if ((mask & OPERATOR_FRIENDLY_NAME) != 0)
+ sb.append("hs20:3,");
+ if ((mask & WAN_METRICS) != 0)
+ sb.append("hs20:4,");
+ if ((mask & CONNECTION_CAPABILITY) != 0)
+ sb.append("hs20:5,");
+ if ((mask & OSU_PROVIDER) != 0)
+ sb.append("hs20:8,");
+ if (sb.length() > 0)
+ sb.deleteCharAt(sb.length() - 1);
+ return sb.toString();
+ }
+
+ @Override
+ public String toString() {
+ StringBuffer sb = new StringBuffer();
+
+ sb.append("BSSID: ").append("(").append(bssid).append(")");
+
+ if (venueName != null)
+ sb.append(" venueName: ").append("(")
+ .append(venueName.replace("\n", "\\n")).append(")");
+
+ if (networkAuthTypeList != null) {
+ sb.append(" networkAuthType: ");
+ for (NetworkAuthType auth : networkAuthTypeList)
+ sb.append("(").append(auth.toString()).append(")");
+ }
+
+ if (roamingConsortiumList != null) {
+ sb.append(" roamingConsortium: ");
+ for (String oi : roamingConsortiumList)
+ sb.append("(").append(oi).append(")");
+ }
+
+ if (ipAddrTypeAvailability != null) {
+ sb.append(" ipAddrTypeAvaibility: ").append("(")
+ .append(ipAddrTypeAvailability.toString()).append(")");
+ }
+
+ if (naiRealmList != null) {
+ sb.append(" naiRealm: ");
+ for (NaiRealm realm : naiRealmList)
+ sb.append("(").append(realm.toString()).append(")");
+ }
+
+ if (cellularNetworkList != null) {
+ sb.append(" cellularNetwork: ");
+ for (CellularNetwork plmn : cellularNetworkList)
+ sb.append("(").append(plmn.toString()).append(")");
+ }
+
+ if (domainNameList != null) {
+ sb.append(" domainName: ");
+ for (String fqdn : domainNameList)
+ sb.append("(").append(fqdn).append(")");
+ }
+
+ if (operatorFriendlyName != null)
+ sb.append(" operatorFriendlyName: ").append("(")
+ .append(operatorFriendlyName).append(")");
+
+ if (wanMetrics != null)
+ sb.append(" wanMetrics: ").append("(")
+ .append(wanMetrics.toString()).append(")");
+
+ if (connectionCapabilityList != null) {
+ sb.append(" connectionCapability: ");
+ for (IpProtoPort ip : connectionCapabilityList)
+ sb.append("(").append(ip.toString()).append(")");
+ }
+
+ if (osuProviderList != null) {
+ sb.append(" osuProviderList: ");
+ for (WifiPasspointOsuProvider osu : osuProviderList)
+ sb.append("(").append(osu.toString()).append(")");
+ }
+
+ return sb.toString();
+ }
+
+ /** Implement the Parcelable interface {@hide} */
+ @Override
+ public void writeToParcel(Parcel out, int flags) {
+ out.writeString(bssid);
+ out.writeString(venueName);
+
+ if (networkAuthTypeList == null) {
+ out.writeInt(0);
+ } else {
+ out.writeInt(networkAuthTypeList.size());
+ for (NetworkAuthType auth : networkAuthTypeList) {
+ out.writeInt(auth.type);
+ out.writeString(auth.redirectUrl);
+ }
+ }
+
+ if (roamingConsortiumList == null) {
+ out.writeInt(0);
+ } else {
+ out.writeInt(roamingConsortiumList.size());
+ for (String oi : roamingConsortiumList)
+ out.writeString(oi);
+ }
+
+ if (ipAddrTypeAvailability == null) {
+ out.writeInt(IpAddressType.NULL_VALUE);
+ } else {
+ out.writeInt(ipAddrTypeAvailability.availability);
+ }
+
+ if (naiRealmList == null) {
+ out.writeInt(0);
+ } else {
+ out.writeInt(naiRealmList.size());
+ for (NaiRealm realm : naiRealmList) {
+ out.writeInt(realm.encoding);
+ out.writeString(realm.realm);
+ }
+ }
+
+ if (cellularNetworkList == null) {
+ out.writeInt(0);
+ } else {
+ out.writeInt(cellularNetworkList.size());
+ for (CellularNetwork plmn : cellularNetworkList) {
+ out.writeString(plmn.mcc);
+ out.writeString(plmn.mnc);
+ }
+ }
+
+
+ if (domainNameList == null) {
+ out.writeInt(0);
+ } else {
+ out.writeInt(domainNameList.size());
+ for (String fqdn : domainNameList)
+ out.writeString(fqdn);
+ }
+
+ out.writeString(operatorFriendlyName);
+
+ if (wanMetrics == null) {
+ out.writeInt(0);
+ } else {
+ out.writeInt(1);
+ out.writeInt(wanMetrics.wanInfo);
+ out.writeLong(wanMetrics.downlinkSpeed);
+ out.writeLong(wanMetrics.uplinkSpeed);
+ out.writeInt(wanMetrics.downlinkLoad);
+ out.writeInt(wanMetrics.uplinkLoad);
+ out.writeInt(wanMetrics.lmd);
+ }
+
+ if (connectionCapabilityList == null) {
+ out.writeInt(0);
+ } else {
+ out.writeInt(connectionCapabilityList.size());
+ for (IpProtoPort ip : connectionCapabilityList) {
+ out.writeInt(ip.proto);
+ out.writeInt(ip.port);
+ out.writeInt(ip.status);
+ }
+ }
+
+ if (osuProviderList == null) {
+ out.writeInt(0);
+ } else {
+ out.writeInt(osuProviderList.size());
+ for (WifiPasspointOsuProvider osu : osuProviderList)
+ osu.writeToParcel(out, flags);
+ }
+ }
+
+ /** Implement the Parcelable interface {@hide} */
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ /** Implement the Parcelable interface {@hide} */
+ public static final Parcelable.Creator<WifiPasspointInfo> CREATOR =
+ new Parcelable.Creator<WifiPasspointInfo>() {
+ @Override
+ public WifiPasspointInfo createFromParcel(Parcel in) {
+ WifiPasspointInfo p = new WifiPasspointInfo();
+ int n;
+
+ p.bssid = in.readString();
+ p.venueName = in.readString();
+
+ n = in.readInt();
+ if (n > 0) {
+ p.networkAuthTypeList = new ArrayList<NetworkAuthType>();
+ for (int i = 0; i < n; i++) {
+ NetworkAuthType auth = new NetworkAuthType();
+ auth.type = in.readInt();
+ auth.redirectUrl = in.readString();
+ p.networkAuthTypeList.add(auth);
+ }
+ }
+
+ n = in.readInt();
+ if (n > 0) {
+ p.roamingConsortiumList = new ArrayList<String>();
+ for (int i = 0; i < n; i++)
+ p.roamingConsortiumList.add(in.readString());
+ }
+
+ n = in.readInt();
+ if (n != IpAddressType.NULL_VALUE) {
+ p.ipAddrTypeAvailability = new IpAddressType();
+ p.ipAddrTypeAvailability.availability = n;
+ }
+
+ n = in.readInt();
+ if (n > 0) {
+ p.naiRealmList = new ArrayList<NaiRealm>();
+ for (int i = 0; i < n; i++) {
+ NaiRealm realm = new NaiRealm();
+ realm.encoding = in.readInt();
+ realm.realm = in.readString();
+ p.naiRealmList.add(realm);
+ }
+ }
+
+ n = in.readInt();
+ if (n > 0) {
+ p.cellularNetworkList = new ArrayList<CellularNetwork>();
+ for (int i = 0; i < n; i++) {
+ CellularNetwork plmn = new CellularNetwork();
+ plmn.mcc = in.readString();
+ plmn.mnc = in.readString();
+ p.cellularNetworkList.add(plmn);
+ }
+ }
+
+ n = in.readInt();
+ if (n > 0) {
+ p.domainNameList = new ArrayList<String>();
+ for (int i = 0; i < n; i++)
+ p.domainNameList.add(in.readString());
+ }
+
+ p.operatorFriendlyName = in.readString();
+
+ n = in.readInt();
+ if (n > 0) {
+ p.wanMetrics = new WanMetrics();
+ p.wanMetrics.wanInfo = in.readInt();
+ p.wanMetrics.downlinkSpeed = in.readLong();
+ p.wanMetrics.uplinkSpeed = in.readLong();
+ p.wanMetrics.downlinkLoad = in.readInt();
+ p.wanMetrics.uplinkLoad = in.readInt();
+ p.wanMetrics.lmd = in.readInt();
+ }
+
+ n = in.readInt();
+ if (n > 0) {
+ p.connectionCapabilityList = new ArrayList<IpProtoPort>();
+ for (int i = 0; i < n; i++) {
+ IpProtoPort ip = new IpProtoPort();
+ ip.proto = in.readInt();
+ ip.port = in.readInt();
+ ip.status = in.readInt();
+ p.connectionCapabilityList.add(ip);
+ }
+ }
+
+ n = in.readInt();
+ if (n > 0) {
+ p.osuProviderList = new ArrayList<WifiPasspointOsuProvider>();
+ for (int i = 0; i < n; i++) {
+ WifiPasspointOsuProvider osu = WifiPasspointOsuProvider.CREATOR
+ .createFromParcel(in);
+ p.osuProviderList.add(osu);
+ }
+ }
+
+ return p;
+ }
+
+ @Override
+ public WifiPasspointInfo[] newArray(int size) {
+ return new WifiPasspointInfo[size];
+ }
+ };
+}
diff --git a/wifi/java/android/net/wifi/passpoint/WifiPasspointManager.java b/wifi/java/android/net/wifi/passpoint/WifiPasspointManager.java
new file mode 100644
index 0000000..b9b17eb
--- /dev/null
+++ b/wifi/java/android/net/wifi/passpoint/WifiPasspointManager.java
@@ -0,0 +1,567 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net.wifi.passpoint;
+
+import android.content.Context;
+import android.net.wifi.ScanResult;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.Message;
+import android.os.Messenger;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.os.RemoteException;
+import android.util.Log;
+
+import com.android.internal.util.AsyncChannel;
+import com.android.internal.util.Protocol;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+
+/**
+ * Provides APIs for managing Wifi Passpoint credentials.
+ * @hide
+ */
+public class WifiPasspointManager {
+
+ private static final String TAG = "PasspointManager";
+
+ private static final boolean DBG = true;
+
+ /* Passpoint states values */
+
+ /** Passpoint is in an unknown state. This should only occur in boot time */
+ public static final int PASSPOINT_STATE_UNKNOWN = 0;
+
+ /** Passpoint is disabled. This occurs when wifi is disabled */
+ public static final int PASSPOINT_STATE_DISABLED = 1;
+
+ /** Passpoint is enabled and in discovery state */
+ public static final int PASSPOINT_STATE_DISCOVERY = 2;
+
+ /** Passpoint is enabled and in access state */
+ public static final int PASSPOINT_STATE_ACCESS = 3;
+
+ /** Passpoint is enabled and in provisioning state */
+ public static final int PASSPOINT_STATE_PROVISION = 4;
+
+ /* Passpoint callback error codes */
+
+ /** Indicates that the operation failed due to an internal error */
+ public static final int REASON_ERROR = 0;
+
+ /** Indicates that the operation failed because wifi is disabled */
+ public static final int REASON_WIFI_DISABLED = 1;
+
+ /** Indicates that the operation failed because the framework is busy */
+ public static final int REASON_BUSY = 2;
+
+ /** Indicates that the operation failed because parameter is invalid */
+ public static final int REASON_INVALID_PARAMETER = 3;
+
+ /** Indicates that the operation failed because the server is not trusted */
+ public static final int REASON_NOT_TRUSTED = 4;
+
+ /**
+ * protocol supported for Passpoint
+ */
+ public static final String PROTOCOL_DM = "OMA-DM-ClientInitiated";
+
+ /**
+ * protocol supported for Passpoint
+ */
+ public static final String PROTOCOL_SOAP = "SPP-ClientInitiated";
+
+ /* Passpoint broadcasts */
+
+ /**
+ * Broadcast intent action indicating that the state of Passpoint
+ * connectivity has changed
+ */
+ public static final String PASSPOINT_STATE_CHANGED_ACTION =
+ "android.net.wifi.passpoint.STATE_CHANGE";
+
+ /**
+ * Broadcast intent action indicating that the saved Passpoint credential
+ * list has changed
+ */
+ public static final String PASSPOINT_CRED_CHANGED_ACTION =
+ "android.net.wifi.passpoint.CRED_CHANGE";
+
+ /**
+ * Broadcast intent action indicating that Passpoint online sign up is
+ * avaiable.
+ */
+ public static final String PASSPOINT_OSU_AVAILABLE_ACTION =
+ "android.net.wifi.passpoint.OSU_AVAILABLE";
+
+ /**
+ * Broadcast intent action indicating that user remediation is required
+ */
+ public static final String PASSPOINT_USER_REM_REQ_ACTION =
+ "android.net.wifi.passpoint.USER_REM_REQ";
+
+ /**
+ * Interface for callback invocation when framework channel is lost
+ */
+ public interface ChannelListener {
+ /**
+ * The channel to the framework has been disconnected. Application could
+ * try re-initializing using {@link #initialize}
+ */
+ public void onChannelDisconnected();
+ }
+
+ /**
+ * Interface for callback invocation on an application action
+ */
+ public interface ActionListener {
+ /** The operation succeeded */
+ public void onSuccess();
+
+ /**
+ * The operation failed
+ *
+ * @param reason The reason for failure could be one of
+ * {@link #WIFI_DISABLED}, {@link #ERROR} or {@link #BUSY}
+ */
+ public void onFailure(int reason);
+ }
+
+ /**
+ * Interface for callback invocation when doing OSU or user remediation
+ */
+ public interface OsuRemListener {
+ /** The operation succeeded */
+ public void onSuccess();
+
+ /**
+ * The operation failed
+ *
+ * @param reason The reason for failure could be one of
+ * {@link #WIFI_DISABLED}, {@link #ERROR} or {@link #BUSY}
+ */
+ public void onFailure(int reason);
+
+ /**
+ * Browser launch is requried for user interaction. When this callback
+ * is called, app should launch browser / webview to the given URI.
+ *
+ * @param uri URI for browser launch
+ */
+ public void onBrowserLaunch(String uri);
+
+ /**
+ * When this is called, app should dismiss the previously lanched browser.
+ */
+ public void onBrowserDismiss();
+ }
+
+ /**
+ * A channel that connects the application to the wifi passpoint framework.
+ * Most passpoint operations require a Channel as an argument.
+ * An instance of Channel is obtained by doing a call on {@link #initialize}
+ */
+ public static class Channel {
+ private final static int INVALID_LISTENER_KEY = 0;
+
+ private ChannelListener mChannelListener;
+
+ private HashMap<Integer, Object> mListenerMap = new HashMap<Integer, Object>();
+ private HashMap<Integer, Integer> mListenerMapCount = new HashMap<Integer, Integer>();
+ private Object mListenerMapLock = new Object();
+ private int mListenerKey = 0;
+
+ private List<ScanResult> mAnqpRequest = new LinkedList<ScanResult>();
+ private Object mAnqpRequestLock = new Object();
+
+ private AsyncChannel mAsyncChannel;
+ private PasspointHandler mHandler;
+ Context mContext;
+
+ Channel(Context context, Looper looper, ChannelListener l) {
+ mAsyncChannel = new AsyncChannel();
+ mHandler = new PasspointHandler(looper);
+ mChannelListener = l;
+ mContext = context;
+ }
+
+ private int putListener(Object listener) {
+ return putListener(listener, 1);
+ }
+
+ private int putListener(Object listener, int count) {
+ if (listener == null || count <= 0)
+ return INVALID_LISTENER_KEY;
+ int key;
+ synchronized (mListenerMapLock) {
+ do {
+ key = mListenerKey++;
+ } while (key == INVALID_LISTENER_KEY);
+ mListenerMap.put(key, listener);
+ mListenerMapCount.put(key, count);
+ }
+ return key;
+ }
+
+ private Object peekListener(int key) {
+ Log.d(TAG, "peekListener() key=" + key);
+ if (key == INVALID_LISTENER_KEY)
+ return null;
+ synchronized (mListenerMapLock) {
+ return mListenerMap.get(key);
+ }
+ }
+
+
+ private Object getListener(int key, boolean forceRemove) {
+ Log.d(TAG, "getListener() key=" + key + " force=" + forceRemove);
+ if (key == INVALID_LISTENER_KEY)
+ return null;
+ synchronized (mListenerMapLock) {
+ if (!forceRemove) {
+ int count = mListenerMapCount.get(key);
+ Log.d(TAG, "count=" + count);
+ mListenerMapCount.put(key, --count);
+ if (count > 0)
+ return null;
+ }
+ Log.d(TAG, "remove key");
+ mListenerMapCount.remove(key);
+ return mListenerMap.remove(key);
+ }
+ }
+
+ private void anqpRequestStart(ScanResult sr) {
+ Log.d(TAG, "anqpRequestStart sr.bssid=" + sr.BSSID);
+ synchronized (mAnqpRequestLock) {
+ mAnqpRequest.add(sr);
+ }
+ }
+
+ private void anqpRequestFinish(WifiPasspointInfo result) {
+ Log.d(TAG, "anqpRequestFinish pi.bssid=" + result.bssid);
+ synchronized (mAnqpRequestLock) {
+ for (ScanResult sr : mAnqpRequest)
+ if (sr.BSSID.equals(result.bssid)) {
+ Log.d(TAG, "find hit " + result.bssid);
+ sr.passpoint = result;
+ mAnqpRequest.remove(sr);
+ Log.d(TAG, "mAnqpRequest.len=" + mAnqpRequest.size());
+ break;
+ }
+ }
+ }
+
+ private void anqpRequestFinish(ScanResult sr) {
+ Log.d(TAG, "anqpRequestFinish sr.bssid=" + sr.BSSID);
+ synchronized (mAnqpRequestLock) {
+ for (ScanResult sr1 : mAnqpRequest)
+ if (sr1.BSSID.equals(sr.BSSID)) {
+ mAnqpRequest.remove(sr1);
+ break;
+ }
+ }
+ }
+
+ class PasspointHandler extends Handler {
+ PasspointHandler(Looper looper) {
+ super(looper);
+ }
+
+ @Override
+ public void handleMessage(Message message) {
+ Object listener = null;
+
+ switch (message.what) {
+ case AsyncChannel.CMD_CHANNEL_DISCONNECTED:
+ if (mChannelListener != null) {
+ mChannelListener.onChannelDisconnected();
+ mChannelListener = null;
+ }
+ break;
+
+ case REQUEST_ANQP_INFO_SUCCEEDED:
+ WifiPasspointInfo result = (WifiPasspointInfo) message.obj;
+ anqpRequestFinish(result);
+ listener = getListener(message.arg2, false);
+ if (listener != null) {
+ ((ActionListener) listener).onSuccess();
+ }
+ break;
+
+ case REQUEST_ANQP_INFO_FAILED:
+ anqpRequestFinish((ScanResult) message.obj);
+ listener = getListener(message.arg2, false);
+ if (listener == null)
+ getListener(message.arg2, true);
+ if (listener != null) {
+ ((ActionListener) listener).onFailure(message.arg1);
+ }
+ break;
+
+ case START_OSU_SUCCEEDED:
+ listener = getListener(message.arg2, true);
+ if (listener != null) {
+ ((OsuRemListener) listener).onSuccess();
+ }
+ break;
+
+ case START_OSU_FAILED:
+ listener = getListener(message.arg2, true);
+ if (listener != null) {
+ ((OsuRemListener) listener).onFailure(message.arg1);
+ }
+ break;
+
+ case START_OSU_BROWSER:
+ listener = peekListener(message.arg2);
+ if (listener != null) {
+ ParcelableString str = (ParcelableString) message.obj;
+ if (str == null || str.string == null)
+ ((OsuRemListener) listener).onBrowserDismiss();
+ else
+ ((OsuRemListener) listener).onBrowserLaunch(str.string);
+ }
+ break;
+
+ default:
+ Log.d(TAG, "Ignored " + message);
+ break;
+ }
+ }
+ }
+
+ }
+
+ public static class ParcelableString implements Parcelable {
+ public String string;
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel out, int flags) {
+ out.writeString(string);
+ }
+
+ public static final Parcelable.Creator<ParcelableString> CREATOR =
+ new Parcelable.Creator<ParcelableString>() {
+ @Override
+ public ParcelableString createFromParcel(Parcel in) {
+ ParcelableString ret = new ParcelableString();
+ ret.string = in.readString();
+ return ret;
+ }
+ @Override
+ public ParcelableString[] newArray(int size) {
+ return new ParcelableString[size];
+ }
+ };
+ }
+
+ private static final int BASE = Protocol.BASE_WIFI_PASSPOINT_MANAGER;
+
+ public static final int REQUEST_ANQP_INFO = BASE + 1;
+ public static final int REQUEST_ANQP_INFO_FAILED = BASE + 2;
+ public static final int REQUEST_ANQP_INFO_SUCCEEDED = BASE + 3;
+ public static final int REQUEST_OSU_ICON = BASE + 4;
+ public static final int REQUEST_OSU_ICON_FAILED = BASE + 5;
+ public static final int REQUEST_OSU_ICON_SUCCEEDED = BASE + 6;
+ public static final int START_OSU = BASE + 7;
+ public static final int START_OSU_BROWSER = BASE + 8;
+ public static final int START_OSU_FAILED = BASE + 9;
+ public static final int START_OSU_SUCCEEDED = BASE + 10;
+
+ private Context mContext;
+ IWifiPasspointManager mService;
+
+ /**
+ * TODO: doc
+ * @param context
+ * @param service
+ */
+ public WifiPasspointManager(Context context, IWifiPasspointManager service) {
+ mContext = context;
+ mService = service;
+ }
+
+ /**
+ * Registers the application with the framework. This function must be the
+ * first to be called before any async passpoint operations are performed.
+ *
+ * @param srcContext is the context of the source
+ * @param srcLooper is the Looper on which the callbacks are receivied
+ * @param listener for callback at loss of framework communication. Can be
+ * null.
+ * @return Channel instance that is necessary for performing any further
+ * passpoint operations
+ *
+ */
+ public Channel initialize(Context srcContext, Looper srcLooper, ChannelListener listener) {
+ Messenger messenger = getMessenger();
+ if (messenger == null)
+ return null;
+
+ Channel c = new Channel(srcContext, srcLooper, listener);
+ if (c.mAsyncChannel.connectSync(srcContext, c.mHandler, messenger)
+ == AsyncChannel.STATUS_SUCCESSFUL) {
+ return c;
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * STOPSHIP: temp solution, should use supplicant manager instead, check
+ * with b/13931972
+ */
+ public Messenger getMessenger() {
+ try {
+ return mService.getMessenger();
+ } catch (RemoteException e) {
+ return null;
+ }
+ }
+
+ public int getPasspointState() {
+ try {
+ return mService.getPasspointState();
+ } catch (RemoteException e) {
+ return PASSPOINT_STATE_UNKNOWN;
+ }
+ }
+
+ public void requestAnqpInfo(Channel c, List<ScanResult> requested, int mask,
+ ActionListener listener) {
+ Log.d(TAG, "requestAnqpInfo start");
+ Log.d(TAG, "requested.size=" + requested.size());
+ checkChannel(c);
+ List<ScanResult> list = new ArrayList<ScanResult>();
+ for (ScanResult sr : requested)
+ if (sr.capabilities.contains("[HS20]")) {
+ list.add(sr);
+ c.anqpRequestStart(sr);
+ Log.d(TAG, "adding " + sr.BSSID);
+ }
+ int count = list.size();
+ Log.d(TAG, "after filter, count=" + count);
+ if (count == 0) {
+ if (DBG)
+ Log.d(TAG, "ANQP info request contains no HS20 APs, skipped");
+ listener.onSuccess();
+ return;
+ }
+ int key = c.putListener(listener, count);
+ for (ScanResult sr : list)
+ c.mAsyncChannel.sendMessage(REQUEST_ANQP_INFO, mask, key, sr);
+ Log.d(TAG, "requestAnqpInfo end");
+ }
+
+ public void requestOsuIcons(Channel c, List<WifiPasspointOsuProvider> requested,
+ int resolution, ActionListener listener) {
+ }
+
+ public List<WifiPasspointPolicy> requestCredentialMatch(List<ScanResult> requested) {
+ try {
+ return mService.requestCredentialMatch(requested);
+ } catch (RemoteException e) {
+ return null;
+ }
+ }
+
+ /**
+ * Get a list of saved Passpoint credentials. Only those credentials owned
+ * by the caller will be returned.
+ *
+ * @return The list of credentials
+ */
+ public List<WifiPasspointCredential> getCredentials() {
+ try {
+ return mService.getCredentials();
+ } catch (RemoteException e) {
+ return null;
+ }
+ }
+
+ /**
+ * Add a new Passpoint credential.
+ *
+ * @param cred The credential to be added
+ * @return {@code true} if the operation succeeds, {@code false} otherwise
+ */
+ public boolean addCredential(WifiPasspointCredential cred) {
+ try {
+ return mService.addCredential(cred);
+ } catch (RemoteException e) {
+ return false;
+ }
+ }
+
+ /**
+ * Update an existing Passpoint credential. Only system or the owner of this
+ * credential has the permission to do this.
+ *
+ * @param cred The credential to be updated
+ * @return {@code true} if the operation succeeds, {@code false} otherwise
+ */
+ public boolean updateCredential(WifiPasspointCredential cred) {
+ try {
+ return mService.updateCredential(cred);
+ } catch (RemoteException e) {
+ return false;
+ }
+ }
+
+ /**
+ * Remove an existing Passpoint credential. Only system or the owner of this
+ * credential has the permission to do this.
+ *
+ * @param cred The credential to be removed
+ * @return {@code true} if the operation succeeds, {@code false} otherwise
+ */
+ public boolean removeCredential(WifiPasspointCredential cred) {
+ try {
+ return mService.removeCredential(cred);
+ } catch (RemoteException e) {
+ return false;
+ }
+ }
+
+ public void startOsu(Channel c, WifiPasspointOsuProvider osu, OsuRemListener listener) {
+ Log.d(TAG, "startOsu start");
+ checkChannel(c);
+ int key = c.putListener(listener);
+ c.mAsyncChannel.sendMessage(START_OSU, 0, key, osu);
+ Log.d(TAG, "startOsu end");
+ }
+
+ public void startRemediation(Channel c, OsuRemListener listener) {
+ }
+
+ public void connect(WifiPasspointPolicy policy) {
+ }
+
+ private static void checkChannel(Channel c) {
+ if (c == null) throw new IllegalArgumentException("Channel needs to be initialized");
+ }
+}
diff --git a/cmds/app_process/sigchain_proxy.cpp b/wifi/java/android/net/wifi/passpoint/WifiPasspointOsuProvider.aidl
similarity index 72%
copy from cmds/app_process/sigchain_proxy.cpp
copy to wifi/java/android/net/wifi/passpoint/WifiPasspointOsuProvider.aidl
index bb7a678..088136f 100644
--- a/cmds/app_process/sigchain_proxy.cpp
+++ b/wifi/java/android/net/wifi/passpoint/WifiPasspointOsuProvider.aidl
@@ -1,11 +1,11 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
+/**
+ * Copyright (c) 2014, The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
- * http://www.apache.org/licenses/LICENSE-2.0
+ * 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,
@@ -14,4 +14,6 @@
* limitations under the License.
*/
-#include "sigchainlib/sigchain.cc"
+package android.net.wifi.passpoint;
+
+parcelable WifiPasspointOsuProvider;
diff --git a/wifi/java/android/net/wifi/passpoint/WifiPasspointOsuProvider.java b/wifi/java/android/net/wifi/passpoint/WifiPasspointOsuProvider.java
new file mode 100644
index 0000000..b54b70c
--- /dev/null
+++ b/wifi/java/android/net/wifi/passpoint/WifiPasspointOsuProvider.java
@@ -0,0 +1,152 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net.wifi.passpoint;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+
+/** @hide */
+public class WifiPasspointOsuProvider implements Parcelable {
+
+ /** TODO: doc
+ * @hide
+ */
+ public static final int OSU_METHOD_UNKNOWN = -1;
+
+ /** TODO: doc
+ * @hide
+ */
+ public static final int OSU_METHOD_OMADM = 0;
+
+ /** TODO: doc
+ * @hide
+ */
+ public static final int OSU_METHOD_SOAP = 1;
+
+ /** TODO: doc */
+ public String ssid;
+
+ /** TODO: doc */
+ public String friendlyName;
+
+ /** TODO: doc
+ * @hide
+ */
+ public String serverUri;
+
+ /** TODO: doc
+ * @hide
+ */
+ public int osuMethod = OSU_METHOD_UNKNOWN;
+
+ /** TODO: doc */
+ public int iconWidth;
+
+ /** TODO: doc */
+ public int iconHeight;
+
+ /** TODO: doc */
+ public String iconType;
+
+ /** TODO: doc */
+ public String iconFileName;
+
+ /** TODO: doc */
+ public Object icon; // TODO: should change to image format
+
+ /** TODO: doc */
+ public String osuNai;
+
+ /** TODO: doc */
+ public String osuService;
+
+ /** default constructor @hide */
+ public WifiPasspointOsuProvider() {
+ // TODO
+ }
+
+ /** copy constructor @hide */
+ public WifiPasspointOsuProvider(WifiPasspointOsuProvider source) {
+ // TODO
+ }
+
+ @Override
+ public String toString() {
+ StringBuffer sb = new StringBuffer();
+ sb.append("SSID: ").append("<").append(ssid).append(">");
+ if (friendlyName != null)
+ sb.append(" friendlyName: ").append("<").append(friendlyName).append(">");
+ if (serverUri != null)
+ sb.append(" serverUri: ").append("<").append(serverUri).append(">");
+ sb.append(" osuMethod: ").append("<").append(osuMethod).append(">");
+ if (iconFileName != null) {
+ sb.append(" icon: <").append(iconWidth).append("x")
+ .append(iconHeight).append(" ")
+ .append(iconType).append(" ")
+ .append(iconFileName).append(">");
+ }
+ if (osuNai != null)
+ sb.append(" osuNai: ").append("<").append(osuNai).append(">");
+ if (osuService != null)
+ sb.append(" osuService: ").append("<").append(osuService).append(">");
+ return sb.toString();
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel out, int flags) {
+ out.writeString(ssid);
+ out.writeString(friendlyName);
+ out.writeString(serverUri);
+ out.writeInt(osuMethod);
+ out.writeInt(iconWidth);
+ out.writeInt(iconHeight);
+ out.writeString(iconType);
+ out.writeString(iconFileName);
+ out.writeString(osuNai);
+ out.writeString(osuService);
+ // TODO: icon image?
+ }
+
+ public static final Parcelable.Creator<WifiPasspointOsuProvider> CREATOR =
+ new Parcelable.Creator<WifiPasspointOsuProvider>() {
+ @Override
+ public WifiPasspointOsuProvider createFromParcel(Parcel in) {
+ WifiPasspointOsuProvider osu = new WifiPasspointOsuProvider();
+ osu.ssid = in.readString();
+ osu.friendlyName = in.readString();
+ osu.serverUri = in.readString();
+ osu.osuMethod = in.readInt();
+ osu.iconWidth = in.readInt();
+ osu.iconHeight = in.readInt();
+ osu.iconType = in.readString();
+ osu.iconFileName = in.readString();
+ osu.osuNai = in.readString();
+ osu.osuService = in.readString();
+ return osu;
+ }
+
+ @Override
+ public WifiPasspointOsuProvider[] newArray(int size) {
+ return new WifiPasspointOsuProvider[size];
+ }
+ };
+}
diff --git a/cmds/app_process/sigchain_proxy.cpp b/wifi/java/android/net/wifi/passpoint/WifiPasspointPolicy.aidl
similarity index 73%
copy from cmds/app_process/sigchain_proxy.cpp
copy to wifi/java/android/net/wifi/passpoint/WifiPasspointPolicy.aidl
index bb7a678..1d61da0 100644
--- a/cmds/app_process/sigchain_proxy.cpp
+++ b/wifi/java/android/net/wifi/passpoint/WifiPasspointPolicy.aidl
@@ -1,11 +1,11 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
+/**
+ * Copyright (c) 2014, The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
- * http://www.apache.org/licenses/LICENSE-2.0
+ * 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,
@@ -14,4 +14,6 @@
* limitations under the License.
*/
-#include "sigchainlib/sigchain.cc"
+package android.net.wifi.passpoint;
+
+parcelable WifiPasspointPolicy;
diff --git a/wifi/java/android/net/wifi/passpoint/WifiPasspointPolicy.java b/wifi/java/android/net/wifi/passpoint/WifiPasspointPolicy.java
new file mode 100644
index 0000000..f84ac88
--- /dev/null
+++ b/wifi/java/android/net/wifi/passpoint/WifiPasspointPolicy.java
@@ -0,0 +1,386 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net.wifi.passpoint;
+
+import android.net.wifi.WifiConfiguration;
+import android.net.wifi.ScanResult;
+import android.os.Parcelable;
+import android.os.Parcel;
+import android.security.Credentials;
+import android.util.Log;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.util.List;
+
+
+/** @hide */
+public class WifiPasspointPolicy implements Parcelable {
+
+ private final static String TAG = "PasspointPolicy";
+
+ /** @hide */
+ public static final int HOME_SP = 0;
+
+ /** @hide */
+ public static final int ROAMING_PARTNER = 1;
+
+ /** @hide */
+ public static final int UNRESTRICTED = 2;
+
+ private String mName;
+ private int mCredentialPriority;
+ private int mRoamingPriority;
+ private String mBssid;
+ private String mSsid;
+ private WifiPasspointCredential mCredential;
+ private int mRestriction;// Permitted values are "HomeSP", "RoamingPartner", or "Unrestricted"
+ private boolean mIsHomeSp;
+
+ private final String INT_PRIVATE_KEY = "private_key";
+ private final String INT_PHASE2 = "phase2";
+ private final String INT_PASSWORD = "password";
+ private final String INT_IDENTITY = "identity";
+ private final String INT_EAP = "eap";
+ private final String INT_CLIENT_CERT = "client_cert";
+ private final String INT_CA_CERT = "ca_cert";
+ private final String INT_ANONYMOUS_IDENTITY = "anonymous_identity";
+ private final String INT_SIM_SLOT = "sim_slot";
+ private final String INT_ENTERPRISEFIELD_NAME ="android.net.wifi.WifiConfiguration$EnterpriseField";
+ private final String ISO8601DATEFORMAT = "yyyy-MM-dd'T'HH:mm:ss'Z'";
+ private final String ENTERPRISE_PHASE2_MSCHAPV2 = "auth=MSCHAPV2";
+ private final String ENTERPRISE_PHASE2_MSCHAP = "auth=MSCHAP";
+
+ /** @hide */
+ public WifiPasspointPolicy(String name, String ssid,
+ String bssid, WifiPasspointCredential pc,
+ int restriction, boolean ishomesp) {
+ mName = name;
+ if (pc != null) {
+ mCredentialPriority = pc.getPriority();
+ }
+ //PerProviderSubscription/<X+>/Policy/PreferredRoamingPartnerList/<X+>/Priority
+ mRoamingPriority = 128; //default priority value of 128
+ mSsid = ssid;
+ mCredential = pc;
+ mBssid = bssid;
+ mRestriction = restriction;
+ mIsHomeSp = ishomesp;
+ }
+
+ public String getSsid() {
+ return mSsid;
+ }
+
+ /** @hide */
+ public void setBssid(String bssid) {
+ mBssid = bssid;
+ }
+
+ public String getBssid() {
+ return mBssid;
+ }
+
+ /** @hide */
+ public void setRestriction(int r) {
+ mRestriction = r;
+ }
+
+ /** @hide */
+ public int getRestriction() {
+ return mRestriction;
+ }
+
+ /** @hide */
+ public void setHomeSp(boolean b) {
+ mIsHomeSp = b;
+ }
+
+ /** @hide */
+ public boolean isHomeSp() {
+ return mIsHomeSp;
+ }
+
+ /** @hide */
+ public void setCredential(WifiPasspointCredential newCredential) {
+ mCredential = newCredential;
+ }
+
+ public WifiPasspointCredential getCredential() {
+ // TODO: return a copy
+ return mCredential;
+ }
+
+ /** @hide */
+ public void setCredentialPriority(int priority) {
+ mCredentialPriority = priority;
+ }
+
+ /** @hide */
+ public void setRoamingPriority(int priority) {
+ mRoamingPriority = priority;
+ }
+
+ public int getCredentialPriority() {
+ return mCredentialPriority;
+ }
+
+ public int getRoamingPriority() {
+ return mRoamingPriority;
+ }
+
+ public WifiConfiguration createWifiConfiguration() {
+ WifiConfiguration wfg = new WifiConfiguration();
+ if (mBssid != null) {
+ Log.d(TAG, "create bssid:" + mBssid);
+ wfg.BSSID = mBssid;
+ }
+
+ if (mSsid != null) {
+ Log.d(TAG, "create ssid:" + mSsid);
+ wfg.SSID = mSsid;
+ }
+ //TODO: 1. add pmf configuration
+ // 2. add ocsp configuration
+ // 3. add eap-sim configuration
+ /*Key management*/
+ wfg.status = WifiConfiguration.Status.ENABLED;
+ wfg.allowedKeyManagement.clear();
+ wfg.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_EAP);
+ wfg.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.IEEE8021X);
+
+ /*Group Ciphers*/
+ wfg.allowedGroupCiphers.clear();
+ wfg.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP);
+ wfg.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.TKIP);
+
+ /*Protocols*/
+ wfg.allowedProtocols.clear();
+ wfg.allowedProtocols.set(WifiConfiguration.Protocol.RSN);
+ wfg.allowedProtocols.set(WifiConfiguration.Protocol.WPA);
+
+ Class[] enterpriseFieldArray = WifiConfiguration.class.getClasses();
+ Class<?> enterpriseFieldClass = null;
+
+
+ for(Class<?> myClass : enterpriseFieldArray) {
+ if(myClass.getName().equals(INT_ENTERPRISEFIELD_NAME)) {
+ enterpriseFieldClass = myClass;
+ break;
+ }
+ }
+ Log.d(TAG, "class chosen " + enterpriseFieldClass.getName() );
+
+
+ Field anonymousId = null, caCert = null, clientCert = null,
+ eap = null, identity = null, password = null,
+ phase2 = null, privateKey = null;
+
+ Field[] fields = WifiConfiguration.class.getFields();
+
+
+ for (Field tempField : fields) {
+ if (tempField.getName().trim().equals(INT_ANONYMOUS_IDENTITY)) {
+ anonymousId = tempField;
+ Log.d(TAG, "field " + anonymousId.getName() );
+ } else if (tempField.getName().trim().equals(INT_CA_CERT)) {
+ caCert = tempField;
+ } else if (tempField.getName().trim().equals(INT_CLIENT_CERT)) {
+ clientCert = tempField;
+ Log.d(TAG, "field " + clientCert.getName() );
+ } else if (tempField.getName().trim().equals(INT_EAP)) {
+ eap = tempField;
+ Log.d(TAG, "field " + eap.getName() );
+ } else if (tempField.getName().trim().equals(INT_IDENTITY)) {
+ identity = tempField;
+ Log.d(TAG, "field " + identity.getName() );
+ } else if (tempField.getName().trim().equals(INT_PASSWORD)) {
+ password = tempField;
+ Log.d(TAG, "field " + password.getName() );
+ } else if (tempField.getName().trim().equals(INT_PHASE2)) {
+ phase2 = tempField;
+ Log.d(TAG, "field " + phase2.getName() );
+
+ } else if (tempField.getName().trim().equals(INT_PRIVATE_KEY)) {
+ privateKey = tempField;
+ }
+ }
+
+
+ Method setValue = null;
+
+ for(Method m: enterpriseFieldClass.getMethods()) {
+ if(m.getName().trim().equals("setValue")) {
+ Log.d(TAG, "method " + m.getName() );
+ setValue = m;
+ break;
+ }
+ }
+
+ try {
+ // EAP
+ String eapmethod = mCredential.getType();
+ Log.d(TAG, "eapmethod:" + eapmethod);
+ setValue.invoke(eap.get(wfg), eapmethod);
+
+ // Username, password, EAP Phase 2
+ if ("TTLS".equals(eapmethod)) {
+ setValue.invoke(phase2.get(wfg), ENTERPRISE_PHASE2_MSCHAPV2);
+ setValue.invoke(identity.get(wfg), mCredential.getUserName());
+ setValue.invoke(password.get(wfg), mCredential.getPassword());
+ setValue.invoke(anonymousId.get(wfg), "anonymous@" + mCredential.getRealm());
+ }
+
+ // EAP CA Certificate
+ String cacertificate = null;
+ String rootCA = mCredential.getCaRootCertPath();
+ if (rootCA == null){
+ cacertificate = null;
+ } else {
+ cacertificate = "keystore://" + Credentials.WIFI + "HS20" + Credentials.CA_CERTIFICATE + rootCA;
+ }
+ Log.d(TAG, "cacertificate:" + cacertificate);
+ setValue.invoke(caCert.get(wfg), cacertificate);
+
+ //User certificate
+ if ("TLS".equals(eapmethod)) {
+ String usercertificate = null;
+ String privatekey = null;
+ String clientCertPath = mCredential.getClientCertPath();
+ if (clientCertPath != null){
+ privatekey = "keystore://" + Credentials.WIFI + "HS20" + Credentials.USER_PRIVATE_KEY + clientCertPath;
+ usercertificate = "keystore://" + Credentials.WIFI + "HS20" + Credentials.USER_CERTIFICATE + clientCertPath;
+ }
+ Log.d(TAG, "privatekey:" + privatekey);
+ Log.d(TAG, "usercertificate:" + usercertificate);
+ if (privatekey != null && usercertificate != null) {
+ setValue.invoke(privateKey.get(wfg), privatekey);
+ setValue.invoke(clientCert.get(wfg), usercertificate);
+ }
+ }
+ } catch (Exception e) {
+ Log.d(TAG, "createWifiConfiguration err:" + e);
+ }
+
+ return wfg;
+ }
+
+ /** {@inheritDoc} @hide */
+ public int compareTo(WifiPasspointPolicy another) {
+ Log.d(TAG, "this:" + this);
+ Log.d(TAG, "another:" + another);
+
+ if (another == null) {
+ return -1;
+ } else if (this.mIsHomeSp == true && another.isHomeSp() == false) {
+ //home sp priority is higher then roaming
+ Log.d(TAG, "compare HomeSP first, this is HomeSP, another isn't");
+ return -1;
+ } else if ((this.mIsHomeSp == true && another.isHomeSp() == true)) {
+ Log.d(TAG, "both HomeSP");
+ //if both home sp, compare credential priority
+ if (this.mCredentialPriority < another.getCredentialPriority()) {
+ Log.d(TAG, "this priority is higher");
+ return -1;
+ } else if (this.mCredentialPriority == another.getCredentialPriority()) {
+ Log.d(TAG, "both priorities equal");
+ //if priority still the same, compare name(ssid)
+ if (this.mName.compareTo(another.mName) != 0) {
+ Log.d(TAG, "compare mName return:" + this.mName.compareTo(another.mName));
+ return this.mName.compareTo(another.mName);
+ }
+ /**
+ *if name still the same, compare credential
+ *the device may has two more credentials(TLS,SIM..etc)
+ *it can associate to one AP(same ssid). so we should compare by credential
+ */
+ if (this.mCredential != null && another.mCredential != null) {
+ if (this.mCredential.compareTo(another.mCredential) != 0) {
+ Log.d(TAG,
+ "compare mCredential return:" + this.mName.compareTo(another.mName));
+ return this.mCredential.compareTo(another.mCredential);
+ }
+ }
+ } else {
+ return 1;
+ }
+ } else if ((this.mIsHomeSp == false && another.isHomeSp() == false)) {
+ Log.d(TAG, "both RoamingSp");
+ //if both roaming sp, compare roaming priority(preferredRoamingPartnerList/<X+>/priority)
+ if (this.mRoamingPriority < another.getRoamingPriority()) {
+ Log.d(TAG, "this priority is higher");
+ return -1;
+ } else if (this.mRoamingPriority == another.getRoamingPriority()) {//priority equals, compare name
+ Log.d(TAG, "both priorities equal");
+ //if priority still the same, compare name(ssid)
+ if (this.mName.compareTo(another.mName) != 0) {
+ Log.d(TAG, "compare mName return:" + this.mName.compareTo(another.mName));
+ return this.mName.compareTo(another.mName);
+ }
+ //if name still the same, compare credential
+ if (this.mCredential != null && another.mCredential != null) {
+ if (this.mCredential.compareTo(another.mCredential) != 0) {
+ Log.d(TAG,
+ "compare mCredential return:"
+ + this.mCredential.compareTo(another.mCredential));
+ return this.mCredential.compareTo(another.mCredential);
+ }
+ }
+ } else {
+ return 1;
+ }
+ }
+
+ Log.d(TAG, "both policies equal");
+ return 0;
+ }
+
+ @Override
+ /** @hide */
+ public String toString() {
+ return "PasspointPolicy: name=" + mName + " CredentialPriority=" + mCredentialPriority +
+ " mRoamingPriority" + mRoamingPriority +
+ " ssid=" + mSsid + " restriction=" + mRestriction +
+ " ishomesp=" + mIsHomeSp + " Credential=" + mCredential;
+ }
+
+ /** Implement the Parcelable interface {@hide} */
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ /** Implement the Parcelable interface {@hide} */
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ // TODO
+ }
+
+ /** Implement the Parcelable interface {@hide} */
+ public static final Creator<WifiPasspointPolicy> CREATOR =
+ new Creator<WifiPasspointPolicy>() {
+ @Override
+ public WifiPasspointPolicy createFromParcel(Parcel in) {
+ return null;
+ }
+
+ @Override
+ public WifiPasspointPolicy[] newArray(int size) {
+ return new WifiPasspointPolicy[size];
+ }
+ };
+}