Merge "Fix bug 3176330 - Improve documentation around MenuItem.setShowAsAction"
diff --git a/api/current.xml b/api/current.xml
index e022092..19c1384 100644
--- a/api/current.xml
+++ b/api/current.xml
@@ -2484,6 +2484,17 @@
visibility="public"
>
</field>
+<field name="baseline"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="16843565"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
<field name="baselineAlignBottom"
type="int"
transient="false"
@@ -234184,6 +234195,17 @@
visibility="public"
>
</method>
+<method name="getBaselineAlignBottom"
+ return="boolean"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
<method name="getDrawable"
return="android.graphics.drawable.Drawable"
abstract="false"
@@ -234256,6 +234278,32 @@
<parameter name="alpha" type="int">
</parameter>
</method>
+<method name="setBaseline"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="baseline" type="int">
+</parameter>
+</method>
+<method name="setBaselineAlignBottom"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="aligned" type="boolean">
+</parameter>
+</method>
<method name="setColorFilter"
return="void"
abstract="false"
@@ -246683,7 +246731,7 @@
deprecated="not deprecated"
visibility="public"
>
-<parameter name="t" type="T">
+<parameter name="arg0" type="T">
</parameter>
</method>
</interface>
diff --git a/cmds/stagefright/recordvideo.cpp b/cmds/stagefright/recordvideo.cpp
index f8eb514..1264215 100644
--- a/cmds/stagefright/recordvideo.cpp
+++ b/cmds/stagefright/recordvideo.cpp
@@ -264,7 +264,7 @@
}
enc_meta->setInt32(kKeyWidth, width);
enc_meta->setInt32(kKeyHeight, height);
- enc_meta->setInt32(kKeySampleRate, frameRateFps);
+ enc_meta->setInt32(kKeyFrameRate, frameRateFps);
enc_meta->setInt32(kKeyBitRate, bitRateBps);
enc_meta->setInt32(kKeyStride, width);
enc_meta->setInt32(kKeySliceHeight, height);
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index 70e11df..3cead11 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -95,6 +95,7 @@
import java.util.TimeZone;
import java.util.regex.Pattern;
+import dalvik.system.CloseGuard;
import dalvik.system.SamplingProfiler;
final class SuperNotCalledException extends AndroidRuntimeException {
@@ -3726,6 +3727,11 @@
public static final void main(String[] args) {
SamplingProfilerIntegration.start();
+ // CloseGuard defaults to true and can be quite spammy. We
+ // disable it here, but selectively enable it later (via
+ // StrictMode) on debug builds, but using DropBox, not logs.
+ CloseGuard.setEnabled(false);
+
Process.setArgV0("<pre-initialized>");
Looper.prepareMainLooper();
diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java
index 129c29d..dda3107 100644
--- a/core/java/android/app/ContextImpl.java
+++ b/core/java/android/app/ContextImpl.java
@@ -106,9 +106,6 @@
import java.util.List;
import java.util.Map;
import java.util.Set;
-import java.util.WeakHashMap;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.ExecutorService;
class ReceiverRestrictedContext extends ContextWrapper {
ReceiverRestrictedContext(Context base) {
@@ -149,18 +146,9 @@
private final static String TAG = "ApplicationContext";
private final static boolean DEBUG = false;
- private static final Object sSync = new Object();
- private static AlarmManager sAlarmManager;
- private static PowerManager sPowerManager;
- private static ConnectivityManager sConnectivityManager;
- private static ThrottleManager sThrottleManager;
- private static WifiManager sWifiManager;
- private static LocationManager sLocationManager;
- private static CountryDetector sCountryDetector;
private static final HashMap<String, SharedPreferencesImpl> sSharedPrefs =
new HashMap<String, SharedPreferencesImpl>();
- private AudioManager mAudioManager;
/*package*/ LoadedApk mPackageInfo;
private Resources mResources;
/*package*/ ActivityThread mMainThread;
@@ -170,24 +158,8 @@
private int mThemeResource = 0;
private Resources.Theme mTheme = null;
private PackageManager mPackageManager;
- private NotificationManager mNotificationManager = null;
- private ActivityManager mActivityManager = null;
- private WallpaperManager mWallpaperManager = null;
private Context mReceiverRestrictedContext = null;
- private SearchManager mSearchManager = null;
- private SensorManager mSensorManager = null;
- private StorageManager mStorageManager = null;
- private Vibrator mVibrator = null;
- private LayoutInflater mLayoutInflater = null;
- private StatusBarManager mStatusBarManager = null;
- private TelephonyManager mTelephonyManager = null;
- private ClipboardManager mClipboardManager = null;
private boolean mRestricted;
- private AccountManager mAccountManager; // protected by mSync
- private DropBoxManager mDropBoxManager = null;
- private DevicePolicyManager mDevicePolicyManager = null;
- private UiModeManager mUiModeManager = null;
- private DownloadManager mDownloadManager = null;
private final Object mSync = new Object();
@@ -200,6 +172,266 @@
private static final String[] EMPTY_FILE_LIST = {};
+ /**
+ * Override this class when the system service constructor needs a
+ * ContextImpl. Else, use StaticServiceFetcher below.
+ */
+ /*package*/ static class ServiceFetcher {
+ int mContextCacheIndex = -1;
+
+ /**
+ * Main entrypoint; only override if you don't need caching.
+ */
+ public Object getService(ContextImpl ctx) {
+ ArrayList<Object> cache = ctx.mServiceCache;
+ Object service;
+ synchronized (cache) {
+ if (cache.size() == 0) {
+ // Initialize the cache vector on first access.
+ // At this point sNextPerContextServiceCacheIndex
+ // is the number of potential services that are
+ // cached per-Context.
+ for (int i = 0; i < sNextPerContextServiceCacheIndex; i++) {
+ cache.add(null);
+ }
+ } else {
+ service = cache.get(mContextCacheIndex);
+ if (service != null) {
+ return service;
+ }
+ }
+ service = createService(ctx);
+ cache.set(mContextCacheIndex, service);
+ return service;
+ }
+ }
+
+ /**
+ * Override this to create a new per-Context instance of the
+ * service. getService() will handle locking and caching.
+ */
+ public Object createService(ContextImpl ctx) {
+ throw new RuntimeException("Not implemented");
+ }
+ }
+
+ /**
+ * Override this class for services to be cached process-wide.
+ */
+ abstract static class StaticServiceFetcher extends ServiceFetcher {
+ private Object mCachedInstance;
+
+ @Override
+ public final Object getService(ContextImpl unused) {
+ synchronized (StaticServiceFetcher.this) {
+ Object service = mCachedInstance;
+ if (service != null) {
+ return service;
+ }
+ return mCachedInstance = createStaticService();
+ }
+ }
+
+ public abstract Object createStaticService();
+ }
+
+ private static final HashMap<String, ServiceFetcher> SYSTEM_SERVICE_MAP =
+ new HashMap<String, ServiceFetcher>();
+
+ private static int sNextPerContextServiceCacheIndex = 0;
+ private static void registerService(String serviceName, ServiceFetcher fetcher) {
+ if (!(fetcher instanceof StaticServiceFetcher)) {
+ fetcher.mContextCacheIndex = sNextPerContextServiceCacheIndex++;
+ }
+ SYSTEM_SERVICE_MAP.put(serviceName, fetcher);
+ }
+
+ // This one's defined separately and given a variable name so it
+ // can be re-used by getWallpaperManager(), avoiding a HashMap
+ // lookup.
+ private static ServiceFetcher WALLPAPER_FETCHER = new ServiceFetcher() {
+ public Object createService(ContextImpl ctx) {
+ return new WallpaperManager(ctx.getOuterContext(),
+ ctx.mMainThread.getHandler());
+ }};
+
+ static {
+ registerService(ACCESSIBILITY_SERVICE, new ServiceFetcher() {
+ public Object getService(ContextImpl ctx) {
+ return AccessibilityManager.getInstance(ctx);
+ }});
+
+ registerService(ACCOUNT_SERVICE, new ServiceFetcher() {
+ public Object createService(ContextImpl ctx) {
+ IBinder b = ServiceManager.getService(ACCOUNT_SERVICE);
+ IAccountManager service = IAccountManager.Stub.asInterface(b);
+ return new AccountManager(ctx, service);
+ }});
+
+ registerService(ACTIVITY_SERVICE, new ServiceFetcher() {
+ public Object createService(ContextImpl ctx) {
+ return new ActivityManager(ctx.getOuterContext(), ctx.mMainThread.getHandler());
+ }});
+
+ registerService(ALARM_SERVICE, new StaticServiceFetcher() {
+ public Object createStaticService() {
+ IBinder b = ServiceManager.getService(ALARM_SERVICE);
+ IAlarmManager service = IAlarmManager.Stub.asInterface(b);
+ return new AlarmManager(service);
+ }});
+
+ registerService(AUDIO_SERVICE, new ServiceFetcher() {
+ public Object createService(ContextImpl ctx) {
+ return new AudioManager(ctx);
+ }});
+
+ registerService(CLIPBOARD_SERVICE, new ServiceFetcher() {
+ public Object createService(ContextImpl ctx) {
+ return new ClipboardManager(ctx.getOuterContext(),
+ ctx.mMainThread.getHandler());
+ }});
+
+ registerService(CONNECTIVITY_SERVICE, new StaticServiceFetcher() {
+ public Object createStaticService() {
+ IBinder b = ServiceManager.getService(CONNECTIVITY_SERVICE);
+ return new ConnectivityManager(IConnectivityManager.Stub.asInterface(b));
+ }});
+
+ registerService(COUNTRY_DETECTOR, new StaticServiceFetcher() {
+ public Object createStaticService() {
+ IBinder b = ServiceManager.getService(COUNTRY_DETECTOR);
+ return new CountryDetector(ICountryDetector.Stub.asInterface(b));
+ }});
+
+ registerService(DEVICE_POLICY_SERVICE, new ServiceFetcher() {
+ public Object createService(ContextImpl ctx) {
+ return DevicePolicyManager.create(ctx, ctx.mMainThread.getHandler());
+ }});
+
+ registerService(DOWNLOAD_SERVICE, new ServiceFetcher() {
+ public Object createService(ContextImpl ctx) {
+ return new DownloadManager(ctx.getContentResolver(), ctx.getPackageName());
+ }});
+
+ registerService(DROPBOX_SERVICE, new StaticServiceFetcher() {
+ public Object createStaticService() {
+ return createDropBoxManager();
+ }});
+
+ registerService(INPUT_METHOD_SERVICE, new ServiceFetcher() {
+ public Object createService(ContextImpl ctx) {
+ return InputMethodManager.getInstance(ctx);
+ }});
+
+ registerService(KEYGUARD_SERVICE, new ServiceFetcher() {
+ public Object getService(ContextImpl ctx) {
+ // TODO: why isn't this caching it? It wasn't
+ // before, so I'm preserving the old behavior and
+ // using getService(), instead of createService()
+ // which would do the caching.
+ return new KeyguardManager();
+ }});
+
+ registerService(LAYOUT_INFLATER_SERVICE, new ServiceFetcher() {
+ public Object createService(ContextImpl ctx) {
+ return PolicyManager.makeNewLayoutInflater(ctx.getOuterContext());
+ }});
+
+ registerService(LOCATION_SERVICE, new StaticServiceFetcher() {
+ public Object createStaticService() {
+ IBinder b = ServiceManager.getService(LOCATION_SERVICE);
+ return new LocationManager(ILocationManager.Stub.asInterface(b));
+ }});
+
+ registerService(NOTIFICATION_SERVICE, new ServiceFetcher() {
+ public Object createService(ContextImpl ctx) {
+ final Context outerContext = ctx.getOuterContext();
+ return new NotificationManager(
+ new ContextThemeWrapper(outerContext,
+ outerContext.getApplicationInfo().targetSdkVersion >=
+ Build.VERSION_CODES.HONEYCOMB
+ ? com.android.internal.R.style.Theme_Holo_Dialog
+ : com.android.internal.R.style.Theme_Dialog),
+ ctx.mMainThread.getHandler());
+ }});
+
+ // Note: this was previously cached in a static variable, but
+ // constructed using mMainThread.getHandler(), so converting
+ // it to be a regular Context-cached service...
+ registerService(POWER_SERVICE, new ServiceFetcher() {
+ public Object createService(ContextImpl ctx) {
+ IBinder b = ServiceManager.getService(POWER_SERVICE);
+ IPowerManager service = IPowerManager.Stub.asInterface(b);
+ return new PowerManager(service, ctx.mMainThread.getHandler());
+ }});
+
+ registerService(SEARCH_SERVICE, new ServiceFetcher() {
+ public Object createService(ContextImpl ctx) {
+ return new SearchManager(ctx.getOuterContext(),
+ ctx.mMainThread.getHandler());
+ }});
+
+ registerService(SENSOR_SERVICE, new ServiceFetcher() {
+ public Object createService(ContextImpl ctx) {
+ return new SensorManager(ctx.mMainThread.getHandler().getLooper());
+ }});
+
+ registerService(STATUS_BAR_SERVICE, new ServiceFetcher() {
+ public Object createService(ContextImpl ctx) {
+ return new StatusBarManager(ctx.getOuterContext());
+ }});
+
+ registerService(STORAGE_SERVICE, new ServiceFetcher() {
+ public Object createService(ContextImpl ctx) {
+ try {
+ return new StorageManager(ctx.mMainThread.getHandler().getLooper());
+ } catch (RemoteException rex) {
+ Log.e(TAG, "Failed to create StorageManager", rex);
+ return null;
+ }
+ }});
+
+ registerService(TELEPHONY_SERVICE, new ServiceFetcher() {
+ public Object createService(ContextImpl ctx) {
+ return new TelephonyManager(ctx.getOuterContext());
+ }});
+
+ registerService(THROTTLE_SERVICE, new StaticServiceFetcher() {
+ public Object createStaticService() {
+ IBinder b = ServiceManager.getService(THROTTLE_SERVICE);
+ return new ThrottleManager(IThrottleManager.Stub.asInterface(b));
+ }});
+
+ registerService(UI_MODE_SERVICE, new ServiceFetcher() {
+ public Object createService(ContextImpl ctx) {
+ return new UiModeManager();
+ }});
+
+ registerService(VIBRATOR_SERVICE, new ServiceFetcher() {
+ public Object createService(ContextImpl ctx) {
+ return new Vibrator();
+ }});
+
+ registerService(WALLPAPER_SERVICE, WALLPAPER_FETCHER);
+
+ registerService(WIFI_SERVICE, new ServiceFetcher() {
+ public Object createService(ContextImpl ctx) {
+ IBinder b = ServiceManager.getService(WIFI_SERVICE);
+ IWifiManager service = IWifiManager.Stub.asInterface(b);
+ return new WifiManager(service, ctx.mMainThread.getHandler());
+ }});
+
+ registerService(WINDOW_SERVICE, new ServiceFetcher() {
+ public Object getService(ContextImpl ctx) {
+ return WindowManagerImpl.getDefault();
+ }});
+ }
+
+ // The system service cache for the system services that are
+ // cached per-ContextImpl. Package-scoped to avoid accessor
+ // methods.
+ final ArrayList<Object> mServiceCache = new ArrayList<Object>();
+
@Override
public AssetManager getAssets() {
return mResources.getAssets();
@@ -895,273 +1127,12 @@
@Override
public Object getSystemService(String name) {
- if (WINDOW_SERVICE.equals(name)) {
- return WindowManagerImpl.getDefault();
- } else if (LAYOUT_INFLATER_SERVICE.equals(name)) {
- synchronized (mSync) {
- LayoutInflater inflater = mLayoutInflater;
- if (inflater != null) {
- return inflater;
- }
- mLayoutInflater = inflater =
- PolicyManager.makeNewLayoutInflater(getOuterContext());
- return inflater;
- }
- } else if (ACTIVITY_SERVICE.equals(name)) {
- return getActivityManager();
- } else if (INPUT_METHOD_SERVICE.equals(name)) {
- return InputMethodManager.getInstance(this);
- } else if (ALARM_SERVICE.equals(name)) {
- return getAlarmManager();
- } else if (ACCOUNT_SERVICE.equals(name)) {
- return getAccountManager();
- } else if (POWER_SERVICE.equals(name)) {
- return getPowerManager();
- } else if (CONNECTIVITY_SERVICE.equals(name)) {
- return getConnectivityManager();
- } else if (THROTTLE_SERVICE.equals(name)) {
- return getThrottleManager();
- } else if (WIFI_SERVICE.equals(name)) {
- return getWifiManager();
- } else if (NOTIFICATION_SERVICE.equals(name)) {
- return getNotificationManager();
- } else if (KEYGUARD_SERVICE.equals(name)) {
- return new KeyguardManager();
- } else if (ACCESSIBILITY_SERVICE.equals(name)) {
- return AccessibilityManager.getInstance(this);
- } else if (LOCATION_SERVICE.equals(name)) {
- return getLocationManager();
- } else if (COUNTRY_DETECTOR.equals(name)) {
- return getCountryDetector();
- } else if (SEARCH_SERVICE.equals(name)) {
- return getSearchManager();
- } else if (SENSOR_SERVICE.equals(name)) {
- return getSensorManager();
- } else if (STORAGE_SERVICE.equals(name)) {
- return getStorageManager();
- } else if (VIBRATOR_SERVICE.equals(name)) {
- return getVibrator();
- } else if (STATUS_BAR_SERVICE.equals(name)) {
- synchronized (mSync) {
- if (mStatusBarManager == null) {
- mStatusBarManager = new StatusBarManager(getOuterContext());
- }
- return mStatusBarManager;
- }
- } else if (AUDIO_SERVICE.equals(name)) {
- return getAudioManager();
- } else if (TELEPHONY_SERVICE.equals(name)) {
- return getTelephonyManager();
- } else if (CLIPBOARD_SERVICE.equals(name)) {
- return getClipboardManager();
- } else if (WALLPAPER_SERVICE.equals(name)) {
- return getWallpaperManager();
- } else if (DROPBOX_SERVICE.equals(name)) {
- return getDropBoxManager();
- } else if (DEVICE_POLICY_SERVICE.equals(name)) {
- return getDevicePolicyManager();
- } else if (UI_MODE_SERVICE.equals(name)) {
- return getUiModeManager();
- } else if (DOWNLOAD_SERVICE.equals(name)) {
- return getDownloadManager();
- }
-
- return null;
- }
-
- private AccountManager getAccountManager() {
- synchronized (mSync) {
- if (mAccountManager == null) {
- IBinder b = ServiceManager.getService(ACCOUNT_SERVICE);
- IAccountManager service = IAccountManager.Stub.asInterface(b);
- mAccountManager = new AccountManager(this, service);
- }
- return mAccountManager;
- }
- }
-
- private ActivityManager getActivityManager() {
- synchronized (mSync) {
- if (mActivityManager == null) {
- mActivityManager = new ActivityManager(getOuterContext(),
- mMainThread.getHandler());
- }
- }
- return mActivityManager;
- }
-
- private AlarmManager getAlarmManager() {
- synchronized (sSync) {
- if (sAlarmManager == null) {
- IBinder b = ServiceManager.getService(ALARM_SERVICE);
- IAlarmManager service = IAlarmManager.Stub.asInterface(b);
- sAlarmManager = new AlarmManager(service);
- }
- }
- return sAlarmManager;
- }
-
- private PowerManager getPowerManager() {
- synchronized (sSync) {
- if (sPowerManager == null) {
- IBinder b = ServiceManager.getService(POWER_SERVICE);
- IPowerManager service = IPowerManager.Stub.asInterface(b);
- sPowerManager = new PowerManager(service, mMainThread.getHandler());
- }
- }
- return sPowerManager;
- }
-
- private ConnectivityManager getConnectivityManager()
- {
- synchronized (sSync) {
- if (sConnectivityManager == null) {
- IBinder b = ServiceManager.getService(CONNECTIVITY_SERVICE);
- IConnectivityManager service = IConnectivityManager.Stub.asInterface(b);
- sConnectivityManager = new ConnectivityManager(service);
- }
- }
- return sConnectivityManager;
- }
-
- private ThrottleManager getThrottleManager()
- {
- synchronized (sSync) {
- if (sThrottleManager == null) {
- IBinder b = ServiceManager.getService(THROTTLE_SERVICE);
- IThrottleManager service = IThrottleManager.Stub.asInterface(b);
- sThrottleManager = new ThrottleManager(service);
- }
- }
- return sThrottleManager;
- }
-
- private WifiManager getWifiManager()
- {
- synchronized (sSync) {
- if (sWifiManager == null) {
- IBinder b = ServiceManager.getService(WIFI_SERVICE);
- IWifiManager service = IWifiManager.Stub.asInterface(b);
- sWifiManager = new WifiManager(service, mMainThread.getHandler());
- }
- }
- return sWifiManager;
- }
-
- private NotificationManager getNotificationManager() {
- synchronized (mSync) {
- if (mNotificationManager == null) {
- final Context outerContext = getOuterContext();
- mNotificationManager = new NotificationManager(
- new ContextThemeWrapper(outerContext,
- outerContext.getApplicationInfo().targetSdkVersion >=
- Build.VERSION_CODES.HONEYCOMB
- ? com.android.internal.R.style.Theme_Holo_Dialog
- : com.android.internal.R.style.Theme_Dialog),
- mMainThread.getHandler());
- }
- }
- return mNotificationManager;
+ ServiceFetcher fetcher = SYSTEM_SERVICE_MAP.get(name);
+ return fetcher == null ? null : fetcher.getService(this);
}
private WallpaperManager getWallpaperManager() {
- synchronized (mSync) {
- if (mWallpaperManager == null) {
- mWallpaperManager = new WallpaperManager(getOuterContext(),
- mMainThread.getHandler());
- }
- }
- return mWallpaperManager;
- }
-
- private TelephonyManager getTelephonyManager() {
- synchronized (mSync) {
- if (mTelephonyManager == null) {
- mTelephonyManager = new TelephonyManager(getOuterContext());
- }
- }
- return mTelephonyManager;
- }
-
- private ClipboardManager getClipboardManager() {
- synchronized (mSync) {
- if (mClipboardManager == null) {
- mClipboardManager = new ClipboardManager(getOuterContext(),
- mMainThread.getHandler());
- }
- }
- return mClipboardManager;
- }
-
- private LocationManager getLocationManager() {
- synchronized (sSync) {
- if (sLocationManager == null) {
- IBinder b = ServiceManager.getService(LOCATION_SERVICE);
- ILocationManager service = ILocationManager.Stub.asInterface(b);
- sLocationManager = new LocationManager(service);
- }
- }
- return sLocationManager;
- }
-
- private CountryDetector getCountryDetector() {
- synchronized (sSync) {
- if (sCountryDetector == null) {
- IBinder b = ServiceManager.getService(COUNTRY_DETECTOR);
- ICountryDetector service = ICountryDetector.Stub.asInterface(b);
- sCountryDetector = new CountryDetector(service);
- }
- }
- return sCountryDetector;
- }
-
- private SearchManager getSearchManager() {
- synchronized (mSync) {
- if (mSearchManager == null) {
- mSearchManager = new SearchManager(getOuterContext(), mMainThread.getHandler());
- }
- }
- return mSearchManager;
- }
-
- private SensorManager getSensorManager() {
- synchronized (mSync) {
- if (mSensorManager == null) {
- mSensorManager = new SensorManager(mMainThread.getHandler().getLooper());
- }
- }
- return mSensorManager;
- }
-
- private StorageManager getStorageManager() {
- synchronized (mSync) {
- if (mStorageManager == null) {
- try {
- mStorageManager = new StorageManager(mMainThread.getHandler().getLooper());
- } catch (RemoteException rex) {
- Log.e(TAG, "Failed to create StorageManager", rex);
- mStorageManager = null;
- }
- }
- }
- return mStorageManager;
- }
-
- private Vibrator getVibrator() {
- synchronized (mSync) {
- if (mVibrator == null) {
- mVibrator = new Vibrator();
- }
- }
- return mVibrator;
- }
-
- private AudioManager getAudioManager()
- {
- if (mAudioManager == null) {
- mAudioManager = new AudioManager(this);
- }
- return mAudioManager;
+ return (WallpaperManager) WALLPAPER_FETCHER.getService(this);
}
/* package */ static DropBoxManager createDropBoxManager() {
@@ -1177,43 +1148,6 @@
return new DropBoxManager(service);
}
- private DropBoxManager getDropBoxManager() {
- synchronized (mSync) {
- if (mDropBoxManager == null) {
- mDropBoxManager = createDropBoxManager();
- }
- }
- return mDropBoxManager;
- }
-
- private DevicePolicyManager getDevicePolicyManager() {
- synchronized (mSync) {
- if (mDevicePolicyManager == null) {
- mDevicePolicyManager = DevicePolicyManager.create(this,
- mMainThread.getHandler());
- }
- }
- return mDevicePolicyManager;
- }
-
- private UiModeManager getUiModeManager() {
- synchronized (mSync) {
- if (mUiModeManager == null) {
- mUiModeManager = new UiModeManager();
- }
- }
- return mUiModeManager;
- }
-
- private DownloadManager getDownloadManager() {
- synchronized (mSync) {
- if (mDownloadManager == null) {
- mDownloadManager = new DownloadManager(getContentResolver(), getPackageName());
- }
- }
- return mDownloadManager;
- }
-
@Override
public int checkPermission(String permission, int pid, int uid) {
if (permission == null) {
diff --git a/core/java/android/app/DownloadManager.java b/core/java/android/app/DownloadManager.java
index 3a6fd23..0741d41 100644
--- a/core/java/android/app/DownloadManager.java
+++ b/core/java/android/app/DownloadManager.java
@@ -284,7 +284,7 @@
*/
public static final String[] UNDERLYING_COLUMNS = new String[] {
Downloads.Impl._ID,
- Downloads.Impl._DATA,
+ Downloads.Impl._DATA + " AS " + COLUMN_LOCAL_FILENAME,
Downloads.Impl.COLUMN_MEDIAPROVIDER_URI,
Downloads.Impl.COLUMN_DESTINATION,
Downloads.Impl.COLUMN_TITLE,
diff --git a/core/java/android/webkit/ZoomControlEmbedded.java b/core/java/android/webkit/ZoomControlEmbedded.java
index c29e72b..e505614 100644
--- a/core/java/android/webkit/ZoomControlEmbedded.java
+++ b/core/java/android/webkit/ZoomControlEmbedded.java
@@ -40,13 +40,15 @@
mZoomButtonsController.setVisible(true);
- WebSettings settings = mWebView.getSettings();
- int count = settings.getDoubleTapToastCount();
- if (mZoomManager.isInZoomOverview() && count > 0) {
- settings.setDoubleTapToastCount(--count);
- Toast.makeText(mWebView.getContext(),
- com.android.internal.R.string.double_tap_toast,
- Toast.LENGTH_LONG).show();
+ if (mZoomManager.isDoubleTapEnabled()) {
+ WebSettings settings = mWebView.getSettings();
+ int count = settings.getDoubleTapToastCount();
+ if (mZoomManager.isInZoomOverview() && count > 0) {
+ settings.setDoubleTapToastCount(--count);
+ Toast.makeText(mWebView.getContext(),
+ com.android.internal.R.string.double_tap_toast,
+ Toast.LENGTH_LONG).show();
+ }
}
}
}
diff --git a/core/java/android/webkit/ZoomManager.java b/core/java/android/webkit/ZoomManager.java
index c788a53..23f8bd9 100644
--- a/core/java/android/webkit/ZoomManager.java
+++ b/core/java/android/webkit/ZoomManager.java
@@ -510,6 +510,11 @@
}
}
+ public boolean isDoubleTapEnabled() {
+ WebSettings settings = mWebView.getSettings();
+ return settings != null && settings.getUseWideViewPort();
+ }
+
/**
* The double tap gesture can result in different behaviors depending on the
* content that is tapped.
@@ -528,7 +533,7 @@
*/
public void handleDoubleTap(float lastTouchX, float lastTouchY) {
WebSettings settings = mWebView.getSettings();
- if (settings == null || settings.getUseWideViewPort() == false) {
+ if (!isDoubleTapEnabled()) {
return;
}
diff --git a/core/java/android/widget/ImageView.java b/core/java/android/widget/ImageView.java
index bad74d4..555d993 100644
--- a/core/java/android/widget/ImageView.java
+++ b/core/java/android/widget/ImageView.java
@@ -34,6 +34,7 @@
import android.util.Log;
import android.view.RemotableViewMethod;
import android.view.View;
+import android.view.ViewDebug;
import android.widget.RemoteViews.RemoteView;
@@ -84,7 +85,8 @@
private boolean mCropToPadding;
- private boolean mBaselineAligned = false;
+ private int mBaseline = -1;
+ private boolean mBaselineAlignBottom = false;
private static final ScaleType[] sScaleTypeArray = {
ScaleType.MATRIX,
@@ -118,9 +120,12 @@
setImageDrawable(d);
}
- mBaselineAligned = a.getBoolean(
+ mBaselineAlignBottom = a.getBoolean(
com.android.internal.R.styleable.ImageView_baselineAlignBottom, false);
-
+
+ mBaseline = a.getDimensionPixelSize(
+ com.android.internal.R.styleable.ImageView_baseline, -1);
+
setAdjustViewBounds(
a.getBoolean(com.android.internal.R.styleable.ImageView_adjustViewBounds,
false));
@@ -180,7 +185,7 @@
super.invalidateDrawable(dr);
}
}
-
+
@Override
protected boolean onSetAlpha(int alpha) {
if (getBackground() == null) {
@@ -878,9 +883,63 @@
}
}
+ /**
+ * <p>Return the offset of the widget's text baseline from the widget's top
+ * boundary. </p>
+ *
+ * @return the offset of the baseline within the widget's bounds or -1
+ * if baseline alignment is not supported.
+ */
@Override
+ @ViewDebug.ExportedProperty(category = "layout")
public int getBaseline() {
- return mBaselineAligned ? getMeasuredHeight() : -1;
+ if (mBaselineAlignBottom) {
+ return getMeasuredHeight();
+ } else {
+ return mBaseline;
+ }
+ }
+
+ /**
+ * <p>Set the offset of the widget's text baseline from the widget's top
+ * boundary. This value is overridden by the {@link #setBaselineAlignBottom}
+ * property.</p>
+ *
+ * @param baseline The baseline to use, or -1 if none is to be provided.
+ *
+ * @see #setBaseline
+ * @attr ref android.R.styleable#ImageView_baseline
+ */
+ public void setBaseline(int baseline) {
+ if (mBaseline != baseline) {
+ mBaseline = baseline;
+ requestLayout();
+ }
+ }
+
+ /**
+ * Set whether to set the baseline of this view to the bottom of the view.
+ * Setting this value overrides any calls to setBaseline.
+ *
+ * @param aligned If true, the image view will be baseline aligned with
+ * based on its bottom edge.
+ *
+ * @attr ref android.R.styleable#ImageView_baselineAlignBottom
+ */
+ public void setBaselineAlignBottom(boolean aligned) {
+ if (mBaselineAlignBottom != aligned) {
+ mBaselineAlignBottom = aligned;
+ requestLayout();
+ }
+ }
+
+ /**
+ * Return whether this view's baseline will be considered the bottom of the view.
+ *
+ * @see #setBaselineAlignBottom(boolean)
+ */
+ public boolean getBaselineAlignBottom() {
+ return mBaselineAlignBottom;
}
/**
diff --git a/core/java/android/widget/RemoteViewsAdapter.java b/core/java/android/widget/RemoteViewsAdapter.java
index 26eb57c..52d9c08 100644
--- a/core/java/android/widget/RemoteViewsAdapter.java
+++ b/core/java/android/widget/RemoteViewsAdapter.java
@@ -664,7 +664,7 @@
itemId = factory.getItemId(position);
} catch (Exception e) {
// Print the error
- Log.e(TAG, "Error in updateRemoteViewsInfo(" + position + "): " +
+ Log.e(TAG, "Error in updateRemoteViews(" + position + "): " +
e.getMessage());
e.printStackTrace();
@@ -673,6 +673,14 @@
return;
}
+ if (remoteViews == null) {
+ // If a null view was returned, we break early to prevent it from getting
+ // into our cache and causing problems later. The effect is that the child at this
+ // position will remain as a loading view until it is updated.
+ Log.e(TAG, "Error in updateRemoteViews(" + position + "): " + " null RemoteViews " +
+ "returned from RemoteViewsFactory.");
+ return;
+ }
synchronized (mCache) {
// Cache the RemoteViews we loaded
mCache.insert(position, remoteViews, itemId);
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index 5320b10..b143325 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -3869,7 +3869,7 @@
// - ExtractEditText does not call onFocus when it is displayed. Fixing this issue would
// allow to test for hasSelection in onFocusChanged, which would trigger a
// startTextSelectionMode here. TODO
- if (selectionController != null && hasSelection()) {
+ if (this instanceof ExtractEditText && selectionController != null && hasSelection()) {
startSelectionActionMode();
}
@@ -5042,6 +5042,7 @@
}
public void beginBatchEdit() {
+ mInBatchEditControllers = true;
final InputMethodState ims = mInputMethodState;
if (ims != null) {
int nesting = ++ims.mBatchEditNesting;
@@ -5064,6 +5065,7 @@
}
public void endBatchEdit() {
+ mInBatchEditControllers = false;
final InputMethodState ims = mInputMethodState;
if (ims != null) {
int nesting = --ims.mBatchEditNesting;
@@ -6991,26 +6993,21 @@
// Restore previous selection
Selection.setSelection((Spannable)mText, prevStart, prevEnd);
- if (mSelectionModifierCursorController != null &&
- !mSelectionModifierCursorController.isShowing()) {
+ if (hasSelectionController() && !getSelectionController().isShowing()) {
// If the anchors aren't showing, revive them.
- mSelectionModifierCursorController.show();
- } else {
- // Tapping inside the selection displays the cut/copy/paste context menu
- // as long as the anchors are already showing.
- showContextMenu();
+ getSelectionController().show();
}
return;
} else {
// Tapping outside stops selection mode, if any
stopSelectionActionMode();
- if (mInsertionPointCursorController != null) {
- mInsertionPointCursorController.show();
+ if (hasInsertionController()) {
+ getInsertionController().show();
}
}
- } else if (hasSelection() && mSelectionModifierCursorController != null) {
- mSelectionModifierCursorController.show();
+ } else if (hasSelection() && hasSelectionController()) {
+ getSelectionController().show();
}
}
@@ -7043,11 +7040,12 @@
@Override
public boolean onTouchEvent(MotionEvent event) {
final int action = event.getActionMasked();
- if (mInsertionPointCursorController != null) {
- mInsertionPointCursorController.onTouchEvent(event);
+
+ if (hasInsertionController()) {
+ getInsertionController().onTouchEvent(event);
}
- if (mSelectionModifierCursorController != null) {
- mSelectionModifierCursorController.onTouchEvent(event);
+ if (hasSelectionController()) {
+ getSelectionController().onTouchEvent(event);
}
if (action == MotionEvent.ACTION_DOWN) {
@@ -7129,21 +7127,17 @@
|| windowParams.type > WindowManager.LayoutParams.LAST_SUB_WINDOW;
}
- if (windowSupportsHandles && isTextEditable() && mCursorVisible && mLayout != null &&
- !mTextIsSelectable) {
- if (mInsertionPointCursorController == null) {
- mInsertionPointCursorController = new InsertionPointCursorController();
- }
- } else {
- hideInsertionPointCursorController();
+ // TODO Add an extra android:cursorController flag to disable the controller?
+ mInsertionControllerEnabled = windowSupportsHandles && isTextEditable() && mCursorVisible &&
+ mLayout != null && !mTextIsSelectable;
+ mSelectionControllerEnabled = windowSupportsHandles && textCanBeSelected() &&
+ mLayout != null;
+
+ if (!mInsertionControllerEnabled) {
mInsertionPointCursorController = null;
}
- if (windowSupportsHandles && textCanBeSelected() && mLayout != null) {
- if (mSelectionModifierCursorController == null) {
- mSelectionModifierCursorController = new SelectionModifierCursorController();
- }
- } else {
+ if (!mSelectionControllerEnabled) {
// Stop selection mode if the controller becomes unavailable.
if (mSelectionModifierCursorController != null) {
stopSelectionActionMode();
@@ -8348,6 +8342,10 @@
return true;
}
+ if (isInBatchEditMode()) {
+ return false;
+ }
+
final int extendedPaddingTop = getExtendedPaddingTop();
final int extendedPaddingBottom = getExtendedPaddingBottom();
final int compoundPaddingLeft = getCompoundPaddingLeft();
@@ -8387,7 +8385,7 @@
mPositionY = y - TextView.this.mScrollY;
if (isPositionVisible()) {
int[] coords = null;
- if (mContainer.isShowing()){
+ if (mContainer.isShowing()) {
coords = mTempCoords;
TextView.this.getLocationInWindow(coords);
final int containerPositionX = coords[0] + mPositionX;
@@ -8626,6 +8624,10 @@
}
public void show() {
+ if (isInBatchEditMode()) {
+ return;
+ }
+
mIsShowing = true;
updatePosition();
mStartHandle.show();
@@ -8689,6 +8691,10 @@
}
public void updatePosition() {
+ if (!isShowing()) {
+ return;
+ }
+
final int selectionStart = getSelectionStart();
final int selectionEnd = getSelectionEnd();
@@ -8913,8 +8919,62 @@
}
}
+ /**
+ * @return True if this view supports insertion handles.
+ */
+ boolean hasInsertionController() {
+ return mInsertionControllerEnabled;
+ }
- @ViewDebug.ExportedProperty(category = "text")
+ /**
+ * @return True if this view supports selection handles.
+ */
+ boolean hasSelectionController() {
+ return mSelectionControllerEnabled;
+ }
+
+ CursorController getInsertionController() {
+ if (!mInsertionControllerEnabled) {
+ return null;
+ }
+
+ if (mInsertionPointCursorController == null) {
+ mInsertionPointCursorController = new InsertionPointCursorController();
+
+ final ViewTreeObserver observer = getViewTreeObserver();
+ if (observer != null) {
+ observer.addOnTouchModeChangeListener(mInsertionPointCursorController);
+ }
+ }
+
+ return mInsertionPointCursorController;
+ }
+
+ CursorController getSelectionController() {
+ if (!mSelectionControllerEnabled) {
+ return null;
+ }
+
+ if (mSelectionModifierCursorController == null) {
+ mSelectionModifierCursorController = new SelectionModifierCursorController();
+
+ final ViewTreeObserver observer = getViewTreeObserver();
+ if (observer != null) {
+ observer.addOnTouchModeChangeListener(mSelectionModifierCursorController);
+ }
+ }
+
+ return mSelectionModifierCursorController;
+ }
+
+ boolean isInBatchEditMode() {
+ final InputMethodState ims = mInputMethodState;
+ if (ims != null) {
+ return ims.mBatchEditNesting > 0;
+ }
+ return mInBatchEditControllers;
+ }
+
private CharSequence mText;
private CharSequence mTransformed;
private BufferType mBufferType = BufferType.NORMAL;
@@ -8942,10 +9002,14 @@
private Blink mBlink;
private boolean mCursorVisible = true;
- // Cursor Controllers. Null when disabled.
+ // Cursor Controllers.
private CursorController mInsertionPointCursorController;
private CursorController mSelectionModifierCursorController;
private ActionMode mSelectionActionMode;
+ private boolean mInsertionControllerEnabled;
+ private boolean mSelectionControllerEnabled;
+ private boolean mInBatchEditControllers;
+
// These are needed to desambiguate a long click. If the long click comes from ones of these, we
// select from the current cursor position. Otherwise, select from long pressed position.
private boolean mDPadCenterIsDown = false;
diff --git a/core/java/com/android/internal/util/AsyncChannel.java b/core/java/com/android/internal/util/AsyncChannel.java
index b0778dd..0891acc 100644
--- a/core/java/com/android/internal/util/AsyncChannel.java
+++ b/core/java/com/android/internal/util/AsyncChannel.java
@@ -32,51 +32,51 @@
import java.util.Stack;
/**
- * An asynchronous channel between two handlers.
+ * <p>An asynchronous channel between two handlers.</p>
*
- * The handlers maybe in the same process or in another process. There
+ * <p>The handlers maybe in the same process or in another process. There
* are two protocol styles that can be used with an AysncChannel. The
* first is a simple request/reply protocol where the server does
- * not need to know which client is issuing the request.
+ * not need to know which client is issuing the request.</p>
*
- * In a simple request/reply protocol the client/source sends requests to the
+ * <p>In a simple request/reply protocol the client/source sends requests to the
* server/destination. And the server uses the replyToMessage methods.
* In this usage model there is no need for the destination to
- * use the connect methods. The typical sequence of operations is:
- *
- * 1) Client calls AsyncChannel#connect
- * 2) Client receives CMD_CHANNEL_HALF_CONNECTED from AsyncChannel
-
- * 3) Client calls AsyncChannel#sendMessage(msgX)
- * 4) Server receives and processes msgX
- * 5) Server optionally calls AsyncChannel#replyToMessage(msgY)
- * and if sent Client receives and processes msgY
- * 6) Loop to step 3 until done
- *
- * 7) When done Client calls {@link AsyncChannel#disconnect(int)}
- * 8) Client receives CMD_CHANNEL_DISCONNECTED from AsyncChannel
- *
- * A second usage model is where the server/destination needs to know
+ * use the connect methods. The typical sequence of operations is:</p>
+ *<ol>
+ * <li>Client calls AsyncChannel#connect</li>
+ * <li>Client receives CMD_CHANNEL_HALF_CONNECTED from AsyncChannel</li>
+ * <li><code>comm-loop:</code></li>
+ * <li>Client calls AsyncChannel#sendMessage(msgX)</li>
+ * <li>Server receives and processes msgX</li>
+ * <li>Server optionally calls AsyncChannel#replyToMessage(msgY)
+ * and if sent Client receives and processes msgY</li>
+ * <li>Loop to <code>comm-loop</code> until done</li>
+ * <li>When done Client calls {@link AsyncChannel#disconnect(int)}</li>
+ * <li>Client receives CMD_CHANNEL_DISCONNECTED from AsyncChannel</li>
+ *</ol>
+ *<br/>
+ * <p>A second usage model is where the server/destination needs to know
* which client it's connected too. For example the server needs to
* send unsolicited messages back to the client. Or the server keeps
* different state for each client. In this model the server will also
- * use the connect methods. The typical sequence of operation is:
- *
- * 1) Client calls AsyncChannel#connect
- * 2) Client receives CMD_CHANNEL_HALF_CONNECTED from AsyncChannel
- * 3) Client calls AsyncChannel#sendMessage(CMD_CHANNEL_FULL_CONNECTION)
- * 4) Server receives CMD_CHANNEL_FULL_CONNECTION
- * 5) Server calls AsyncChannel#connect
- * 6) Server receives CMD_CHANNEL_HALF_CONNECTED from AsyncChannel
- * 7) Server sends AsyncChannel#sendMessage(CMD_CHANNEL_FULLY_CONNECTED)
- * 8) Client receives CMD_CHANNEL_FULLY_CONNECTED
- *
- * 9) Client/Server uses AsyncChannel#sendMessage/replyToMessage
- * to communicate and perform work
- * 10) Loop to step 9 until done
- *
- * 11) When done Client/Server calls {@link AsyncChannel#disconnect(int)}
- * 12) Client/Server receives CMD_CHANNEL_DISCONNECTED from AsyncChannel
+ * use the connect methods. The typical sequence of operation is:</p>
+ *<ol>
+ * <li>Client calls AsyncChannel#connect</li>
+ * <li>Client receives CMD_CHANNEL_HALF_CONNECTED from AsyncChannel</li>
+ * <li>Client calls AsyncChannel#sendMessage(CMD_CHANNEL_FULL_CONNECTION)</li>
+ * <li>Server receives CMD_CHANNEL_FULL_CONNECTION</li>
+ * <li>Server calls AsyncChannel#connect</li>
+ * <li>Server receives CMD_CHANNEL_HALF_CONNECTED from AsyncChannel</li>
+ * <li>Server sends AsyncChannel#sendMessage(CMD_CHANNEL_FULLY_CONNECTED)</li>
+ * <li>Client receives CMD_CHANNEL_FULLY_CONNECTED</li>
+ * <li><code>comm-loop:</code></li>
+ * <li>Client/Server uses AsyncChannel#sendMessage/replyToMessage
+ * to communicate and perform work</li>
+ * <li>Loop to <code>comm-loop</code> until done</li>
+ * <li>When done Client/Server calls {@link AsyncChannel#disconnect(int)}</li>
+ * <li>Client/Server receives CMD_CHANNEL_DISCONNECTED from AsyncChannel</li>
+ *</ol>
*/
public class AsyncChannel {
/** Log tag */
diff --git a/core/java/com/android/internal/util/HierarchicalStateMachine.java b/core/java/com/android/internal/util/HierarchicalStateMachine.java
index 7920b72..f43f459 100644
--- a/core/java/com/android/internal/util/HierarchicalStateMachine.java
+++ b/core/java/com/android/internal/util/HierarchicalStateMachine.java
@@ -28,64 +28,66 @@
/**
* {@hide}
*
- * A hierarchical state machine is a state machine which processes messages
- * and can have states arranged hierarchically. A state is a <code>HierarchicalState</code>
- * object and must implement <code>processMessage</code> and optionally <code>enter/exit/getName</code>.
+ * <p>A hierarchical state machine is a state machine which processes messages
+ * and can have states arranged hierarchically.</p>
+ *
+ * <p>A state is a <code>HierarchicalState</code> object and must implement
+ * <code>processMessage</code> and optionally <code>enter/exit/getName</code>.
* The enter/exit methods are equivalent to the construction and destruction
* in Object Oriented programming and are used to perform initialization and
* cleanup of the state respectively. The <code>getName</code> method returns the
* name of the state the default implementation returns the class name it may be
* desirable to have this return the name of the state instance name instead.
- * In particular if a particular state class has multiple instances.
+ * In particular if a particular state class has multiple instances.</p>
*
- * When a state machine is created <code>addState</code> is used to build the
+ * <p>When a state machine is created <code>addState</code> is used to build the
* hierarchy and <code>setInitialState</code> is used to identify which of these
* is the initial state. After construction the programmer calls <code>start</code>
* which initializes the state machine and calls <code>enter</code> for all of the initial
* state's hierarchy, starting at its eldest parent. For example given the simple
* state machine below after start is called mP1.enter will have been called and
- * then mS1.enter.
+ * then mS1.enter.</p>
<code>
mP1
/ \
mS2 mS1 ----> initial state
</code>
- * After the state machine is created and started, messages are sent to a state
+ * <p>After the state machine is created and started, messages are sent to a state
* machine using <code>sendMessage</code> and the messages are created using
* <code>obtainMessage</code>. When the state machine receives a message the
* current state's <code>processMessage</code> is invoked. In the above example
* mS1.processMessage will be invoked first. The state may use <code>transitionTo</code>
- * to change the current state to a new state
+ * to change the current state to a new state</p>
*
- * Each state in the state machine may have a zero or one parent states and if
+ * <p>Each state in the state machine may have a zero or one parent states and if
* a child state is unable to handle a message it may have the message processed
* by its parent by returning false or NOT_HANDLED. If a message is never processed
* <code>unhandledMessage</code> will be invoked to give one last chance for the state machine
- * to process the message.
+ * to process the message.</p>
*
- * When all processing is completed a state machine may choose to call
+ * <p>When all processing is completed a state machine may choose to call
* <code>transitionToHaltingState</code>. When the current <code>processingMessage</code>
* returns the state machine will transfer to an internal <code>HaltingState</code>
* and invoke <code>halting</code>. Any message subsequently received by the state
- * machine will cause <code>haltedProcessMessage</code> to be invoked.
+ * machine will cause <code>haltedProcessMessage</code> to be invoked.</p>
*
- * If it is desirable to completely stop the state machine call <code>quit</code>. This
+ * <p>If it is desirable to completely stop the state machine call <code>quit</code>. This
* will exit the current state and its parent and then exit from the controlling thread
- * and no further messages will be processed.
+ * and no further messages will be processed.</p>
*
- * In addition to <code>processMessage</code> each <code>HierarchicalState</code> has
- * an <code>enter</code> method and <code>exit</exit> method which may be overridden.
+ * <p>In addition to <code>processMessage</code> each <code>HierarchicalState</code> has
+ * an <code>enter</code> method and <code>exit</exit> method which may be overridden.</p>
*
- * Since the states are arranged in a hierarchy transitioning to a new state
+ * <p>Since the states are arranged in a hierarchy transitioning to a new state
* causes current states to be exited and new states to be entered. To determine
* the list of states to be entered/exited the common parent closest to
* the current state is found. We then exit from the current state and its
* parent's up to but not including the common parent state and then enter all
* of the new states below the common parent down to the destination state.
* If there is no common parent all states are exited and then the new states
- * are entered.
+ * are entered.</p>
*
- * Two other methods that states can use are <code>deferMessage</code> and
+ * <p>Two other methods that states can use are <code>deferMessage</code> and
* <code>sendMessageAtFrontOfQueue</code>. The <code>sendMessageAtFrontOfQueue</code> sends
* a message but places it on the front of the queue rather than the back. The
* <code>deferMessage</code> causes the message to be saved on a list until a
@@ -93,10 +95,10 @@
* will be put on the front of the state machine queue with the oldest message
* at the front. These will then be processed by the new current state before
* any other messages that are on the queue or might be added later. Both of
- * these are protected and may only be invoked from within a state machine.
+ * these are protected and may only be invoked from within a state machine.</p>
*
- * To illustrate some of these properties we'll use state machine with an 8
- * state hierarchy:
+ * <p>To illustrate some of these properties we'll use state machine with an 8
+ * state hierarchy:</p>
<code>
mP0
/ \
@@ -106,22 +108,21 @@
/ \ \
mS3 mS4 mS5 ---> initial state
</code>
- *
- * After starting mS5 the list of active states is mP0, mP1, mS1 and mS5.
+ * <p>After starting mS5 the list of active states is mP0, mP1, mS1 and mS5.
* So the order of calling processMessage when a message is received is mS5,
* mS1, mP1, mP0 assuming each processMessage indicates it can't handle this
- * message by returning false or NOT_HANDLED.
+ * message by returning false or NOT_HANDLED.</p>
*
- * Now assume mS5.processMessage receives a message it can handle, and during
+ * <p>Now assume mS5.processMessage receives a message it can handle, and during
* the handling determines the machine should change states. It could call
* transitionTo(mS4) and return true or HANDLED. Immediately after returning from
* processMessage the state machine runtime will find the common parent,
* which is mP1. It will then call mS5.exit, mS1.exit, mS2.enter and then
* mS4.enter. The new list of active states is mP0, mP1, mS2 and mS4. So
- * when the next message is received mS4.processMessage will be invoked.
+ * when the next message is received mS4.processMessage will be invoked.</p>
*
- * Now for some concrete examples, here is the canonical HelloWorld as an HSM.
- * It responds with "Hello World" being printed to the log for every message.
+ * <p>Now for some concrete examples, here is the canonical HelloWorld as an HSM.
+ * It responds with "Hello World" being printed to the log for every message.</p>
<code>
class HelloWorld extends HierarchicalStateMachine {
Hsm1(String name) {
@@ -150,79 +151,76 @@
hw.sendMessage(hw.obtainMessage());
}
</code>
- *
- * A more interesting state machine is one with four states
- * with two independent parent states.
+ * <p>A more interesting state machine is one with four states
+ * with two independent parent states.</p>
<code>
mP1 mP2
/ \
mS2 mS1
</code>
- *
- * Here is a description of this state machine using pseudo code.
- *
- *
- * state mP1 {
- * enter { log("mP1.enter"); }
- * exit { log("mP1.exit"); }
- * on msg {
- * CMD_2 {
- * send(CMD_3);
- * defer(msg);
- * transitonTo(mS2);
- * return HANDLED;
- * }
- * return NOT_HANDLED;
- * }
- * }
- *
- * INITIAL
- * state mS1 parent mP1 {
- * enter { log("mS1.enter"); }
- * exit { log("mS1.exit"); }
- * on msg {
- * CMD_1 {
- * transitionTo(mS1);
- * return HANDLED;
- * }
- * return NOT_HANDLED;
- * }
- * }
- *
- * state mS2 parent mP1 {
- * enter { log("mS2.enter"); }
- * exit { log("mS2.exit"); }
- * on msg {
- * CMD_2 {
- * send(CMD_4);
- * return HANDLED;
- * }
- * CMD_3 {
- * defer(msg);
- * transitionTo(mP2);
- * return HANDLED;
- * }
- * return NOT_HANDLED;
- * }
- * }
- *
- * state mP2 {
- * enter {
- * log("mP2.enter");
- * send(CMD_5);
- * }
- * exit { log("mP2.exit"); }
- * on msg {
- * CMD_3, CMD_4 { return HANDLED; }
- * CMD_5 {
- * transitionTo(HaltingState);
- * return HANDLED;
- * }
- * return NOT_HANDLED;
- * }
- * }
- *
- * The implementation is below and also in HierarchicalStateMachineTest:
+ * <p>Here is a description of this state machine using pseudo code.</p>
+ <code>
+state mP1 {
+ enter { log("mP1.enter"); }
+ exit { log("mP1.exit"); }
+ on msg {
+ CMD_2 {
+ send(CMD_3);
+ defer(msg);
+ transitonTo(mS2);
+ return HANDLED;
+ }
+ return NOT_HANDLED;
+ }
+}
+
+INITIAL
+state mS1 parent mP1 {
+ enter { log("mS1.enter"); }
+ exit { log("mS1.exit"); }
+ on msg {
+ CMD_1 {
+ transitionTo(mS1);
+ return HANDLED;
+ }
+ return NOT_HANDLED;
+ }
+}
+
+state mS2 parent mP1 {
+ enter { log("mS2.enter"); }
+ exit { log("mS2.exit"); }
+ on msg {
+ CMD_2 {
+ send(CMD_4);
+ return HANDLED;
+ }
+ CMD_3 {
+ defer(msg);
+ transitionTo(mP2);
+ return HANDLED;
+ }
+ return NOT_HANDLED;
+ }
+}
+
+state mP2 {
+ enter {
+ log("mP2.enter");
+ send(CMD_5);
+ }
+ exit { log("mP2.exit"); }
+ on msg {
+ CMD_3, CMD_4 { return HANDLED; }
+ CMD_5 {
+ transitionTo(HaltingState);
+ return HANDLED;
+ }
+ return NOT_HANDLED;
+ }
+}
+</code>
+ * <p>The implementation is below and also in HierarchicalStateMachineTest:</p>
<code>
class Hsm1 extends HierarchicalStateMachine {
private static final String TAG = "hsm1";
@@ -368,49 +366,47 @@
P2 mP2 = new P2();
}
</code>
- *
- * If this is executed by sending two messages CMD_1 and CMD_2
- * (Note the synchronize is only needed because we use hsm.wait())
- *
- * Hsm1 hsm = makeHsm1();
- * synchronize(hsm) {
- * hsm.sendMessage(obtainMessage(hsm.CMD_1));
- * hsm.sendMessage(obtainMessage(hsm.CMD_2));
- * try {
- * // wait for the messages to be handled
- * hsm.wait();
- * } catch (InterruptedException e) {
- * Log.e(TAG, "exception while waiting " + e.getMessage());
- * }
- * }
- *
- *
- * The output is:
- *
- * D/hsm1 ( 1999): makeHsm1 E
- * D/hsm1 ( 1999): ctor E
- * D/hsm1 ( 1999): ctor X
- * D/hsm1 ( 1999): mP1.enter
- * D/hsm1 ( 1999): mS1.enter
- * D/hsm1 ( 1999): makeHsm1 X
- * D/hsm1 ( 1999): mS1.processMessage what=1
- * D/hsm1 ( 1999): mS1.exit
- * D/hsm1 ( 1999): mS1.enter
- * D/hsm1 ( 1999): mS1.processMessage what=2
- * D/hsm1 ( 1999): mP1.processMessage what=2
- * D/hsm1 ( 1999): mS1.exit
- * D/hsm1 ( 1999): mS2.enter
- * D/hsm1 ( 1999): mS2.processMessage what=2
- * D/hsm1 ( 1999): mS2.processMessage what=3
- * D/hsm1 ( 1999): mS2.exit
- * D/hsm1 ( 1999): mP1.exit
- * D/hsm1 ( 1999): mP2.enter
- * D/hsm1 ( 1999): mP2.processMessage what=3
- * D/hsm1 ( 1999): mP2.processMessage what=4
- * D/hsm1 ( 1999): mP2.processMessage what=5
- * D/hsm1 ( 1999): mP2.exit
- * D/hsm1 ( 1999): halting
- *
+ * <p>If this is executed by sending two messages CMD_1 and CMD_2
+ * (Note the synchronize is only needed because we use hsm.wait())</p>
+<code>
+Hsm1 hsm = makeHsm1();
+synchronize(hsm) {
+ hsm.sendMessage(obtainMessage(hsm.CMD_1));
+ hsm.sendMessage(obtainMessage(hsm.CMD_2));
+ try {
+ // wait for the messages to be handled
+ hsm.wait();
+ } catch (InterruptedException e) {
+ Log.e(TAG, "exception while waiting " + e.getMessage());
+ }
+}
+</code>
+ * <p>The output is:</p>
+<code>
+D/hsm1 ( 1999): makeHsm1 E
+D/hsm1 ( 1999): ctor E
+D/hsm1 ( 1999): ctor X
+D/hsm1 ( 1999): mP1.enter
+D/hsm1 ( 1999): mS1.enter
+D/hsm1 ( 1999): makeHsm1 X
+D/hsm1 ( 1999): mS1.processMessage what=1
+D/hsm1 ( 1999): mS1.exit
+D/hsm1 ( 1999): mS1.enter
+D/hsm1 ( 1999): mS1.processMessage what=2
+D/hsm1 ( 1999): mP1.processMessage what=2
+D/hsm1 ( 1999): mS1.exit
+D/hsm1 ( 1999): mS2.enter
+D/hsm1 ( 1999): mS2.processMessage what=2
+D/hsm1 ( 1999): mS2.processMessage what=3
+D/hsm1 ( 1999): mS2.exit
+D/hsm1 ( 1999): mP1.exit
+D/hsm1 ( 1999): mP2.enter
+D/hsm1 ( 1999): mP2.processMessage what=3
+D/hsm1 ( 1999): mP2.processMessage what=4
+D/hsm1 ( 1999): mP2.processMessage what=5
+D/hsm1 ( 1999): mP2.exit
+D/hsm1 ( 1999): halting
+</code>
*/
public class HierarchicalStateMachine {
diff --git a/core/jni/android_emoji_EmojiFactory.cpp b/core/jni/android_emoji_EmojiFactory.cpp
index 63550fb..f653b36 100644
--- a/core/jni/android_emoji_EmojiFactory.cpp
+++ b/core/jni/android_emoji_EmojiFactory.cpp
@@ -4,6 +4,7 @@
#define LOG_TAG "EmojiFactory_jni"
#include <utils/Log.h>
#include <utils/String8.h>
+#include <utils/String16.h>
#include "EmojiFactory.h"
#include <nativehelper/JNIHelp.h>
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index 9348822..0b61202 100755
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -2055,6 +2055,9 @@
<attr name="baselineAlignBottom" format="boolean" />
<!-- If true, the image will be cropped to fit within its padding. -->
<attr name="cropToPadding" format="boolean" />
+ <!-- The offset of the baseline within this view. See {see android.view.View#getBaseline}
+ for details -->
+ <attr name="baseline" format="dimension" />
</declare-styleable>
<declare-styleable name="ToggleButton">
<!-- The text for the button when it is checked. -->
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index 6e14527..ad4e7a2 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -1376,6 +1376,7 @@
<public type="attr" name="progressBarPadding" />
<public type="attr" name="animationResolution" />
<public type="attr" name="state_accelerated" />
+ <public type="attr" name="baseline" />
<public type="anim" name="animator_fade_in" />
<public type="anim" name="animator_fade_out" />
diff --git a/core/res/res/values/styles.xml b/core/res/res/values/styles.xml
index 8bec87b..b2db9b4 100644
--- a/core/res/res/values/styles.xml
+++ b/core/res/res/values/styles.xml
@@ -155,12 +155,6 @@
<item name="windowExitAnimation">@anim/shrink_fade_out_from_bottom</item>
</style>
- <!-- {@hide} -->
- <style name="Animation.SlidingCard">
- <item name="windowEnterAnimation">@anim/slide_in_up</item>
- <item name="windowExitAnimation">@anim/slide_out_down</item>
- </style>
-
<!-- Window animations that are applied to input method overlay windows. -->
<style name="Animation.InputMethod">
<item name="windowEnterAnimation">@anim/input_method_enter</item>
diff --git a/core/tests/coretests/src/android/os/AsyncChannelTest.java b/core/tests/coretests/src/com/android/internal/util/AsyncChannelTest.java
similarity index 83%
rename from core/tests/coretests/src/android/os/AsyncChannelTest.java
rename to core/tests/coretests/src/com/android/internal/util/AsyncChannelTest.java
index 43c8290..7088650 100644
--- a/core/tests/coretests/src/android/os/AsyncChannelTest.java
+++ b/core/tests/coretests/src/com/android/internal/util/AsyncChannelTest.java
@@ -14,8 +14,9 @@
* limitations under the License.
*/
-package android.os;
+package com.android.internal.util;
+import android.os.Debug;
import android.test.suitebuilder.annotation.SmallTest;
import android.util.Log;
@@ -26,13 +27,17 @@
*/
public class AsyncChannelTest extends TestCase {
private static final boolean DBG = true;
- private static final boolean WAIT_FOR_DEBUGGER = true;
+ private static final boolean WAIT_FOR_DEBUGGER = false;
private static final String TAG = "AsyncChannelTest";
@SmallTest
public void test1() throws Exception {
+ if (DBG) log("test1");
if (WAIT_FOR_DEBUGGER) Debug.waitForDebugger();
- Log.d(TAG, "test1");
assertTrue(1 == 1);
}
+
+ protected void log(String s) {
+ Log.d(TAG, s);
+ }
}
diff --git a/core/tests/coretests/src/android/os/HierarchicalStateMachineTest.java b/core/tests/coretests/src/com/android/internal/util/HierarchicalStateMachineTest.java
similarity index 99%
rename from core/tests/coretests/src/android/os/HierarchicalStateMachineTest.java
rename to core/tests/coretests/src/com/android/internal/util/HierarchicalStateMachineTest.java
index 6820987..36666c4 100644
--- a/core/tests/coretests/src/android/os/HierarchicalStateMachineTest.java
+++ b/core/tests/coretests/src/com/android/internal/util/HierarchicalStateMachineTest.java
@@ -14,7 +14,13 @@
* limitations under the License.
*/
-package android.os;
+package com.android.internal.util;
+
+import android.os.Debug;
+import android.os.HandlerThread;
+import android.os.Looper;
+import android.os.Message;
+import android.os.SystemClock;
import com.android.internal.util.HierarchicalState;
import com.android.internal.util.HierarchicalStateMachine;
@@ -28,8 +34,6 @@
/**
* Test for HierarchicalStateMachine.
- *
- * @author wink@google.com (Wink Saville)
*/
public class HierarchicalStateMachineTest extends TestCase {
private static final int TEST_CMD_1 = 1;
@@ -40,7 +44,7 @@
private static final int TEST_CMD_6 = 6;
private static final boolean DBG = true;
- private static final boolean WAIT_FOR_DEBUGGER = true;
+ private static final boolean WAIT_FOR_DEBUGGER = false;
private static final String TAG = "HierarchicalStateMachineTest";
/**
@@ -92,7 +96,7 @@
@SmallTest
public void testStateMachineQuitTest() throws Exception {
- //if (WAIT_FOR_DEBUGGER) Debug.waitForDebugger();
+ if (WAIT_FOR_DEBUGGER) Debug.waitForDebugger();
StateMachineQuitTest smQuitTest = new StateMachineQuitTest("smQuitTest");
smQuitTest.start();
diff --git a/include/utils/String16.h b/include/utils/String16.h
index 07a0c11..584f53f 100644
--- a/include/utils/String16.h
+++ b/include/utils/String16.h
@@ -19,39 +19,12 @@
#include <utils/Errors.h>
#include <utils/SharedBuffer.h>
-
-#include <stdint.h>
-#include <sys/types.h>
+#include <utils/Unicode.h>
// ---------------------------------------------------------------------------
extern "C" {
-typedef uint16_t char16_t;
-
-// Standard string functions on char16 strings.
-int strcmp16(const char16_t *, const char16_t *);
-int strncmp16(const char16_t *s1, const char16_t *s2, size_t n);
-size_t strlen16(const char16_t *);
-size_t strnlen16(const char16_t *, size_t);
-char16_t *strcpy16(char16_t *, const char16_t *);
-char16_t *strncpy16(char16_t *, const char16_t *, size_t);
-
-// Version of comparison that supports embedded nulls.
-// This is different than strncmp() because we don't stop
-// at a nul character and consider the strings to be different
-// if the lengths are different (thus we need to supply the
-// lengths of both strings). This can also be used when
-// your string is not nul-terminated as it will have the
-// equivalent result as strcmp16 (unlike strncmp16).
-int strzcmp16(const char16_t *s1, size_t n1, const char16_t *s2, size_t n2);
-
-// Version of strzcmp16 for comparing strings in different endianness.
-int strzcmp16_h_n(const char16_t *s1H, size_t n1, const char16_t *s2N, size_t n2);
-
-// Convert UTF-8 to UTF-16 including surrogate pairs
-void utf8_to_utf16(const uint8_t *src, size_t srcLen, char16_t* dst, const size_t dstLen);
-
}
// ---------------------------------------------------------------------------
diff --git a/include/utils/String8.h b/include/utils/String8.h
index cef8eca..b36f128 100644
--- a/include/utils/String8.h
+++ b/include/utils/String8.h
@@ -18,122 +18,16 @@
#define ANDROID_STRING8_H
#include <utils/Errors.h>
+#include <utils/SharedBuffer.h>
+#include <utils/Unicode.h>
-// Need this for the char16_t type; String8.h should not
-// be depedent on the String16 class.
-#include <utils/String16.h>
-
-#include <stdint.h>
-#include <string.h>
-#include <sys/types.h>
-
-// ---------------------------------------------------------------------------
-
-extern "C" {
-
-typedef uint32_t char32_t;
-
-size_t strlen32(const char32_t *);
-size_t strnlen32(const char32_t *, size_t);
-
-/*
- * Returns the length of "src" when "src" is valid UTF-8 string.
- * Returns 0 if src is NULL, 0-length string or non UTF-8 string.
- * This function should be used to determine whether "src" is valid UTF-8
- * characters with valid unicode codepoints. "src" must be null-terminated.
- *
- * If you are going to use other GetUtf... functions defined in this header
- * with string which may not be valid UTF-8 with valid codepoint (form 0 to
- * 0x10FFFF), you should use this function before calling others, since the
- * other functions do not check whether the string is valid UTF-8 or not.
- *
- * If you do not care whether "src" is valid UTF-8 or not, you should use
- * strlen() as usual, which should be much faster.
- */
-size_t utf8_length(const char *src);
-
-/*
- * Returns the UTF-32 length of "src".
- */
-size_t utf32_length(const char *src, size_t src_len);
-
-/*
- * Returns the UTF-8 length of "src".
- */
-size_t utf8_length_from_utf16(const char16_t *src, size_t src_len);
-
-/*
- * Returns the UTF-8 length of "src".
- */
-size_t utf8_length_from_utf32(const char32_t *src, size_t src_len);
-
-/*
- * Returns the unicode value at "index".
- * Returns -1 when the index is invalid (equals to or more than "src_len").
- * If returned value is positive, it is able to be converted to char32_t, which
- * is unsigned. Then, if "next_index" is not NULL, the next index to be used is
- * stored in "next_index". "next_index" can be NULL.
- */
-int32_t utf32_at(const char *src, size_t src_len,
- size_t index, size_t *next_index);
-
-/*
- * Stores a UTF-32 string converted from "src" in "dst", if "dst_length" is not
- * large enough to store the string, the part of the "src" string is stored
- * into "dst".
- * Returns the size actually used for storing the string.
- * "dst" is not null-terminated when dst_len is fully used (like strncpy).
- */
-size_t utf8_to_utf32(const char* src, size_t src_len,
- char32_t* dst, size_t dst_len);
-
-/*
- * Stores a UTF-8 string converted from "src" in "dst", if "dst_length" is not
- * large enough to store the string, the part of the "src" string is stored
- * into "dst" as much as possible. See the examples for more detail.
- * Returns the size actually used for storing the string.
- * dst" is not null-terminated when dst_len is fully used (like strncpy).
- *
- * Example 1
- * "src" == \u3042\u3044 (\xE3\x81\x82\xE3\x81\x84)
- * "src_len" == 2
- * "dst_len" >= 7
- * ->
- * Returned value == 6
- * "dst" becomes \xE3\x81\x82\xE3\x81\x84\0
- * (note that "dst" is null-terminated)
- *
- * Example 2
- * "src" == \u3042\u3044 (\xE3\x81\x82\xE3\x81\x84)
- * "src_len" == 2
- * "dst_len" == 5
- * ->
- * Returned value == 3
- * "dst" becomes \xE3\x81\x82\0
- * (note that "dst" is null-terminated, but \u3044 is not stored in "dst"
- * since "dst" does not have enough size to store the character)
- *
- * Example 3
- * "src" == \u3042\u3044 (\xE3\x81\x82\xE3\x81\x84)
- * "src_len" == 2
- * "dst_len" == 6
- * ->
- * Returned value == 6
- * "dst" becomes \xE3\x81\x82\xE3\x81\x84
- * (note that "dst" is NOT null-terminated, like strncpy)
- */
-size_t utf32_to_utf8(const char32_t* src, size_t src_len,
- char* dst, size_t dst_len);
-
-size_t utf16_to_utf8(const char16_t* src, size_t src_len,
- char* dst, size_t dst_len);
-
-}
+#include <string.h> // for strcmp
// ---------------------------------------------------------------------------
namespace android {
+class String16;
class TextOutput;
//! This is a string holding UTF-8 characters. Does not allow the value more
@@ -182,7 +76,7 @@
size_t getUtf32Length() const;
int32_t getUtf32At(size_t index,
size_t *next_index) const;
- size_t getUtf32(char32_t* dst, size_t dst_len) const;
+ void getUtf32(char32_t* dst) const;
inline String8& operator=(const String8& other);
inline String8& operator=(const char* other);
diff --git a/include/utils/Unicode.h b/include/utils/Unicode.h
new file mode 100644
index 0000000..6afb291
--- /dev/null
+++ b/include/utils/Unicode.h
@@ -0,0 +1,161 @@
+/*
+ * Copyright (C) 2005 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_UNICODE_H
+#define ANDROID_UNICODE_H
+
+#include <sys/types.h>
+#include <stdint.h>
+
+extern "C" {
+
+typedef uint32_t char32_t;
+typedef uint16_t char16_t;
+
+// Standard string functions on char16_t strings.
+int strcmp16(const char16_t *, const char16_t *);
+int strncmp16(const char16_t *s1, const char16_t *s2, size_t n);
+size_t strlen16(const char16_t *);
+size_t strnlen16(const char16_t *, size_t);
+char16_t *strcpy16(char16_t *, const char16_t *);
+char16_t *strncpy16(char16_t *, const char16_t *, size_t);
+
+// Version of comparison that supports embedded nulls.
+// This is different than strncmp() because we don't stop
+// at a nul character and consider the strings to be different
+// if the lengths are different (thus we need to supply the
+// lengths of both strings). This can also be used when
+// your string is not nul-terminated as it will have the
+// equivalent result as strcmp16 (unlike strncmp16).
+int strzcmp16(const char16_t *s1, size_t n1, const char16_t *s2, size_t n2);
+
+// Version of strzcmp16 for comparing strings in different endianness.
+int strzcmp16_h_n(const char16_t *s1H, size_t n1, const char16_t *s2N, size_t n2);
+
+// Standard string functions on char32_t strings.
+size_t strlen32(const char32_t *);
+size_t strnlen32(const char32_t *, size_t);
+
+/**
+ * Measure the length of a UTF-32 string in UTF-8. If the string is invalid
+ * such as containing a surrogate character, -1 will be returned.
+ */
+ssize_t utf32_to_utf8_length(const char32_t *src, size_t src_len);
+
+/**
+ * Stores a UTF-8 string converted from "src" in "dst", if "dst_length" is not
+ * large enough to store the string, the part of the "src" string is stored
+ * into "dst" as much as possible. See the examples for more detail.
+ * Returns the size actually used for storing the string.
+ * dst" is not null-terminated when dst_len is fully used (like strncpy).
+ *
+ * Example 1
+ * "src" == \u3042\u3044 (\xE3\x81\x82\xE3\x81\x84)
+ * "src_len" == 2
+ * "dst_len" >= 7
+ * ->
+ * Returned value == 6
+ * "dst" becomes \xE3\x81\x82\xE3\x81\x84\0
+ * (note that "dst" is null-terminated)
+ *
+ * Example 2
+ * "src" == \u3042\u3044 (\xE3\x81\x82\xE3\x81\x84)
+ * "src_len" == 2
+ * "dst_len" == 5
+ * ->
+ * Returned value == 3
+ * "dst" becomes \xE3\x81\x82\0
+ * (note that "dst" is null-terminated, but \u3044 is not stored in "dst"
+ * since "dst" does not have enough size to store the character)
+ *
+ * Example 3
+ * "src" == \u3042\u3044 (\xE3\x81\x82\xE3\x81\x84)
+ * "src_len" == 2
+ * "dst_len" == 6
+ * ->
+ * Returned value == 6
+ * "dst" becomes \xE3\x81\x82\xE3\x81\x84
+ * (note that "dst" is NOT null-terminated, like strncpy)
+ */
+void utf32_to_utf8(const char32_t* src, size_t src_len, char* dst);
+
+/**
+ * Returns the unicode value at "index".
+ * Returns -1 when the index is invalid (equals to or more than "src_len").
+ * If returned value is positive, it is able to be converted to char32_t, which
+ * is unsigned. Then, if "next_index" is not NULL, the next index to be used is
+ * stored in "next_index". "next_index" can be NULL.
+ */
+int32_t utf32_from_utf8_at(const char *src, size_t src_len, size_t index, size_t *next_index);
+
+
+/**
+ * Returns the UTF-8 length of UTF-16 string "src".
+ */
+ssize_t utf16_to_utf8_length(const char16_t *src, size_t src_len);
+
+/**
+ * Converts a UTF-16 string to UTF-8. The destination buffer must be large
+ * enough to fit the UTF-16 as measured by utf16_to_utf8_length with an added
+ * NULL terminator.
+ */
+void utf16_to_utf8(const char16_t* src, size_t src_len, char* dst);
+
+/**
+ * Returns the length of "src" when "src" is valid UTF-8 string.
+ * Returns 0 if src is NULL or 0-length string. Returns -1 when the source
+ * is an invalid string.
+ *
+ * This function should be used to determine whether "src" is valid UTF-8
+ * characters with valid unicode codepoints. "src" must be null-terminated.
+ *
+ * If you are going to use other utf8_to_... functions defined in this header
+ * with string which may not be valid UTF-8 with valid codepoint (form 0 to
+ * 0x10FFFF), you should use this function before calling others, since the
+ * other functions do not check whether the string is valid UTF-8 or not.
+ *
+ * If you do not care whether "src" is valid UTF-8 or not, you should use
+ * strlen() as usual, which should be much faster.
+ */
+ssize_t utf8_length(const char *src);
+
+/**
+ * Measure the length of a UTF-32 string.
+ */
+size_t utf8_to_utf32_length(const char *src, size_t src_len);
+
+/**
+ * Stores a UTF-32 string converted from "src" in "dst". "dst" must be large
+ * enough to store the entire converted string as measured by
+ * utf8_to_utf32_length plus space for a NULL terminator.
+ */
+void utf8_to_utf32(const char* src, size_t src_len, char32_t* dst);
+
+/**
+ * Returns the UTF-16 length of UTF-8 string "src".
+ */
+ssize_t utf8_to_utf16_length(const uint8_t* src, size_t srcLen);
+
+/**
+ * Convert UTF-8 to UTF-16 including surrogate pairs. The destination buffer
+ * must be large enough to hold the result as measured by utf8_to_utf16_length
+ * plus an added NULL terminator.
+ */
+void utf8_to_utf16(const uint8_t* src, size_t srcLen, char16_t* dst);
+
+}
+
+#endif
diff --git a/libs/camera/Camera.cpp b/libs/camera/Camera.cpp
index 148e864..450971d 100644
--- a/libs/camera/Camera.cpp
+++ b/libs/camera/Camera.cpp
@@ -372,6 +372,9 @@
}
if (listener != NULL) {
listener->postDataTimestamp(timestamp, msgType, dataPtr);
+ } else {
+ LOGW("No listener was set. Drop a recording frame.");
+ releaseRecordingFrame(dataPtr);
}
}
diff --git a/libs/rs/rsFont.cpp b/libs/rs/rsFont.cpp
index 33b0f51..96e350d 100644
--- a/libs/rs/rsFont.cpp
+++ b/libs/rs/rsFont.cpp
@@ -174,7 +174,7 @@
while (glyphsLeft > 0) {
- int32_t utfChar = utf32_at(text, len, index, &nextIndex);
+ int32_t utfChar = utf32_from_utf8_at(text, len, index, &nextIndex);
// Reached the end of the string or encountered
if (utfChar < 0) {
diff --git a/libs/utils/Android.mk b/libs/utils/Android.mk
index eb75ed8..05a9674 100644
--- a/libs/utils/Android.mk
+++ b/libs/utils/Android.mk
@@ -41,6 +41,7 @@
TextOutput.cpp \
Threads.cpp \
Timers.cpp \
+ Unicode.cpp \
VectorImpl.cpp \
ZipFileCRO.cpp \
ZipFileRO.cpp \
diff --git a/libs/utils/ResourceTypes.cpp b/libs/utils/ResourceTypes.cpp
index f287298..bbf5093 100644
--- a/libs/utils/ResourceTypes.cpp
+++ b/libs/utils/ResourceTypes.cpp
@@ -444,15 +444,51 @@
}
}
-#define DECODE_LENGTH(str, chrsz, len) \
- len = *(str); \
- if (*(str)&(1<<(chrsz*8-1))) { \
- (str)++; \
- len = (((len)&((1<<(chrsz*8-1))-1))<<(chrsz*8)) + *(str); \
- } \
- (str)++;
+/**
+ * Strings in UTF-16 format have length indicated by a length encoded in the
+ * stored data. It is either 1 or 2 characters of length data. This allows a
+ * maximum length of 0x7FFFFFF (2147483647 bytes), but if you're storing that
+ * much data in a string, you're abusing them.
+ *
+ * If the high bit is set, then there are two characters or 4 bytes of length
+ * data encoded. In that case, drop the high bit of the first character and
+ * add it together with the next character.
+ */
+static inline size_t
+decodeLength(const char16_t** str)
+{
+ size_t len = **str;
+ if ((len & 0x8000) != 0) {
+ (*str)++;
+ len = ((len & 0x7FFF) << 16) | **str;
+ }
+ (*str)++;
+ return len;
+}
-const uint16_t* ResStringPool::stringAt(size_t idx, size_t* outLen) const
+/**
+ * Strings in UTF-8 format have length indicated by a length encoded in the
+ * stored data. It is either 1 or 2 characters of length data. This allows a
+ * maximum length of 0x7FFF (32767 bytes), but you should consider storing
+ * text in another way if you're using that much data in a single string.
+ *
+ * If the high bit is set, then there are two characters or 2 bytes of length
+ * data encoded. In that case, drop the high bit of the first character and
+ * add it together with the next character.
+ */
+static inline size_t
+decodeLength(const uint8_t** str)
+{
+ size_t len = **str;
+ if ((len & 0x80) != 0) {
+ (*str)++;
+ len = ((len & 0x7F) << 8) | **str;
+ }
+ (*str)++;
+ return len;
+}
+
+const uint16_t* ResStringPool::stringAt(size_t idx, size_t* u16len) const
{
if (mError == NO_ERROR && idx < mHeader->stringCount) {
const bool isUTF8 = (mHeader->flags&ResStringPool_header::UTF8_FLAG) != 0;
@@ -461,37 +497,51 @@
if (!isUTF8) {
const char16_t* strings = (char16_t*)mStrings;
const char16_t* str = strings+off;
- DECODE_LENGTH(str, sizeof(char16_t), *outLen)
- if ((uint32_t)(str+*outLen-strings) < mStringPoolSize) {
+
+ *u16len = decodeLength(&str);
+ if ((uint32_t)(str+*u16len-strings) < mStringPoolSize) {
return str;
} else {
LOGW("Bad string block: string #%d extends to %d, past end at %d\n",
- (int)idx, (int)(str+*outLen-strings), (int)mStringPoolSize);
+ (int)idx, (int)(str+*u16len-strings), (int)mStringPoolSize);
}
} else {
const uint8_t* strings = (uint8_t*)mStrings;
- const uint8_t* str = strings+off;
- DECODE_LENGTH(str, sizeof(uint8_t), *outLen)
- size_t encLen;
- DECODE_LENGTH(str, sizeof(uint8_t), encLen)
- if ((uint32_t)(str+encLen-strings) < mStringPoolSize) {
+ const uint8_t* u8str = strings+off;
+
+ *u16len = decodeLength(&u8str);
+ size_t u8len = decodeLength(&u8str);
+
+ // encLen must be less than 0x7FFF due to encoding.
+ if ((uint32_t)(u8str+u8len-strings) < mStringPoolSize) {
AutoMutex lock(mDecodeLock);
+
if (mCache[idx] != NULL) {
return mCache[idx];
}
- char16_t *u16str = (char16_t *)calloc(*outLen+1, sizeof(char16_t));
+
+ ssize_t actualLen = utf8_to_utf16_length(u8str, u8len);
+ if (actualLen < 0 || (size_t)actualLen != *u16len) {
+ LOGW("Bad string block: string #%lld decoded length is not correct "
+ "%lld vs %llu\n",
+ (long long)idx, (long long)actualLen, (long long)*u16len);
+ return NULL;
+ }
+
+ char16_t *u16str = (char16_t *)calloc(*u16len+1, sizeof(char16_t));
if (!u16str) {
LOGW("No memory when trying to allocate decode cache for string #%d\n",
(int)idx);
return NULL;
}
- const unsigned char *u8src = reinterpret_cast<const unsigned char *>(str);
- utf8_to_utf16(u8src, encLen, u16str, *outLen);
+
+ utf8_to_utf16(u8str, u8len, u16str);
mCache[idx] = u16str;
return u16str;
} else {
- LOGW("Bad string block: string #%d extends to %d, past end at %d\n",
- (int)idx, (int)(str+encLen-strings), (int)mStringPoolSize);
+ LOGW("Bad string block: string #%lld extends to %lld, past end at %lld\n",
+ (long long)idx, (long long)(u8str+u8len-strings),
+ (long long)mStringPoolSize);
}
}
} else {
@@ -512,9 +562,8 @@
if (isUTF8) {
const uint8_t* strings = (uint8_t*)mStrings;
const uint8_t* str = strings+off;
- DECODE_LENGTH(str, sizeof(uint8_t), *outLen)
- size_t encLen;
- DECODE_LENGTH(str, sizeof(uint8_t), encLen)
+ *outLen = decodeLength(&str);
+ size_t encLen = decodeLength(&str);
if ((uint32_t)(str+encLen-strings) < mStringPoolSize) {
return (const char*)str;
} else {
diff --git a/libs/utils/String16.cpp b/libs/utils/String16.cpp
index eab7b2b..4ce1664 100644
--- a/libs/utils/String16.cpp
+++ b/libs/utils/String16.cpp
@@ -18,228 +18,17 @@
#include <utils/Debug.h>
#include <utils/Log.h>
+#include <utils/Unicode.h>
#include <utils/String8.h>
#include <utils/TextOutput.h>
#include <utils/threads.h>
#include <private/utils/Static.h>
-#ifdef HAVE_WINSOCK
-# undef nhtol
-# undef htonl
-# undef nhtos
-# undef htons
-
-# ifdef HAVE_LITTLE_ENDIAN
-# define ntohl(x) ( ((x) << 24) | (((x) >> 24) & 255) | (((x) << 8) & 0xff0000) | (((x) >> 8) & 0xff00) )
-# define htonl(x) ntohl(x)
-# define ntohs(x) ( (((x) << 8) & 0xff00) | (((x) >> 8) & 255) )
-# define htons(x) ntohs(x)
-# else
-# define ntohl(x) (x)
-# define htonl(x) (x)
-# define ntohs(x) (x)
-# define htons(x) (x)
-# endif
-#else
-# include <netinet/in.h>
-#endif
-
#include <memory.h>
#include <stdio.h>
#include <ctype.h>
-// ---------------------------------------------------------------------------
-
-int strcmp16(const char16_t *s1, const char16_t *s2)
-{
- char16_t ch;
- int d = 0;
-
- while ( 1 ) {
- d = (int)(ch = *s1++) - (int)*s2++;
- if ( d || !ch )
- break;
- }
-
- return d;
-}
-
-int strncmp16(const char16_t *s1, const char16_t *s2, size_t n)
-{
- char16_t ch;
- int d = 0;
-
- while ( n-- ) {
- d = (int)(ch = *s1++) - (int)*s2++;
- if ( d || !ch )
- break;
- }
-
- return d;
-}
-
-char16_t *strcpy16(char16_t *dst, const char16_t *src)
-{
- char16_t *q = dst;
- const char16_t *p = src;
- char16_t ch;
-
- do {
- *q++ = ch = *p++;
- } while ( ch );
-
- return dst;
-}
-
-size_t strlen16(const char16_t *s)
-{
- const char16_t *ss = s;
- while ( *ss )
- ss++;
- return ss-s;
-}
-
-
-char16_t *strncpy16(char16_t *dst, const char16_t *src, size_t n)
-{
- char16_t *q = dst;
- const char16_t *p = src;
- char ch;
-
- while (n) {
- n--;
- *q++ = ch = *p++;
- if ( !ch )
- break;
- }
-
- *q = 0;
-
- return dst;
-}
-
-size_t strnlen16(const char16_t *s, size_t maxlen)
-{
- const char16_t *ss = s;
-
- /* Important: the maxlen test must precede the reference through ss;
- since the byte beyond the maximum may segfault */
- while ((maxlen > 0) && *ss) {
- ss++;
- maxlen--;
- }
- return ss-s;
-}
-
-int strzcmp16(const char16_t *s1, size_t n1, const char16_t *s2, size_t n2)
-{
- const char16_t* e1 = s1+n1;
- const char16_t* e2 = s2+n2;
-
- while (s1 < e1 && s2 < e2) {
- const int d = (int)*s1++ - (int)*s2++;
- if (d) {
- return d;
- }
- }
-
- return n1 < n2
- ? (0 - (int)*s2)
- : (n1 > n2
- ? ((int)*s1 - 0)
- : 0);
-}
-
-int strzcmp16_h_n(const char16_t *s1H, size_t n1, const char16_t *s2N, size_t n2)
-{
- const char16_t* e1 = s1H+n1;
- const char16_t* e2 = s2N+n2;
-
- while (s1H < e1 && s2N < e2) {
- const char16_t c2 = ntohs(*s2N);
- const int d = (int)*s1H++ - (int)c2;
- s2N++;
- if (d) {
- return d;
- }
- }
-
- return n1 < n2
- ? (0 - (int)ntohs(*s2N))
- : (n1 > n2
- ? ((int)*s1H - 0)
- : 0);
-}
-
-static inline size_t
-utf8_char_len(uint8_t ch)
-{
- return ((0xe5000000 >> ((ch >> 3) & 0x1e)) & 3) + 1;
-}
-
-#define UTF8_SHIFT_AND_MASK(unicode, byte) (unicode)<<=6; (unicode) |= (0x3f & (byte));
-
-static inline uint32_t
-utf8_to_utf32(const uint8_t *src, size_t length)
-{
- uint32_t unicode;
-
- switch (length)
- {
- case 1:
- return src[0];
- case 2:
- unicode = src[0] & 0x1f;
- UTF8_SHIFT_AND_MASK(unicode, src[1])
- return unicode;
- case 3:
- unicode = src[0] & 0x0f;
- UTF8_SHIFT_AND_MASK(unicode, src[1])
- UTF8_SHIFT_AND_MASK(unicode, src[2])
- return unicode;
- case 4:
- unicode = src[0] & 0x07;
- UTF8_SHIFT_AND_MASK(unicode, src[1])
- UTF8_SHIFT_AND_MASK(unicode, src[2])
- UTF8_SHIFT_AND_MASK(unicode, src[3])
- return unicode;
- default:
- return 0xffff;
- }
-
- //printf("Char at %p: len=%d, utf-16=%p\n", src, length, (void*)result);
-}
-
-void
-utf8_to_utf16(const uint8_t *src, size_t srcLen,
- char16_t* dst, const size_t dstLen)
-{
- const uint8_t* const end = src + srcLen;
- const char16_t* const dstEnd = dst + dstLen;
- while (src < end && dst < dstEnd) {
- size_t len = utf8_char_len(*src);
- uint32_t codepoint = utf8_to_utf32((const uint8_t*)src, len);
-
- // Convert the UTF32 codepoint to one or more UTF16 codepoints
- if (codepoint <= 0xFFFF) {
- // Single UTF16 character
- *dst++ = (char16_t) codepoint;
- } else {
- // Multiple UTF16 characters with surrogates
- codepoint = codepoint - 0x10000;
- *dst++ = (char16_t) ((codepoint >> 10) + 0xD800);
- *dst++ = (char16_t) ((codepoint & 0x3FF) + 0xDC00);
- }
-
- src += len;
- }
- if (dst < dstEnd) {
- *dst = 0;
- }
-}
-
-// ---------------------------------------------------------------------------
namespace android {
@@ -270,37 +59,33 @@
// ---------------------------------------------------------------------------
-static char16_t* allocFromUTF8(const char* in, size_t len)
+static char16_t* allocFromUTF8(const char* u8str, size_t u8len)
{
- if (len == 0) return getEmptyString();
-
- size_t chars = 0;
- const char* end = in+len;
- const char* p = in;
-
- while (p < end) {
- chars++;
- int utf8len = utf8_char_len(*p);
- uint32_t codepoint = utf8_to_utf32((const uint8_t*)p, utf8len);
- if (codepoint > 0xFFFF) chars++; // this will be a surrogate pair in utf16
- p += utf8len;
+ if (u8len == 0) return getEmptyString();
+
+ const uint8_t* u8cur = (const uint8_t*) u8str;
+
+ const ssize_t u16len = utf8_to_utf16_length(u8cur, u8len);
+ if (u16len < 0) {
+ return getEmptyString();
}
-
- size_t bufSize = (chars+1)*sizeof(char16_t);
- SharedBuffer* buf = SharedBuffer::alloc(bufSize);
+
+ const uint8_t* const u8end = u8cur + u8len;
+
+ SharedBuffer* buf = SharedBuffer::alloc(sizeof(char16_t)*(u16len+1));
if (buf) {
- p = in;
- char16_t* str = (char16_t*)buf->data();
-
- utf8_to_utf16((const uint8_t*)p, len, str, bufSize);
+ u8cur = (const uint8_t*) u8str;
+ char16_t* u16str = (char16_t*)buf->data();
+
+ utf8_to_utf16(u8cur, u8len, u16str);
//printf("Created UTF-16 string from UTF-8 \"%s\":", in);
//printHexData(1, str, buf->size(), 16, 1);
//printf("\n");
- return str;
+ return u16str;
}
-
+
return getEmptyString();
}
diff --git a/libs/utils/String8.cpp b/libs/utils/String8.cpp
index 6358fc4..c8dc083 100644
--- a/libs/utils/String8.cpp
+++ b/libs/utils/String8.cpp
@@ -17,6 +17,8 @@
#include <utils/String8.h>
#include <utils/Log.h>
+#include <utils/Unicode.h>
+#include <utils/SharedBuffer.h>
#include <utils/String16.h>
#include <utils/TextOutput.h>
#include <utils/threads.h>
@@ -34,94 +36,10 @@
namespace android {
-static const char32_t kByteMask = 0x000000BF;
-static const char32_t kByteMark = 0x00000080;
-
-// Surrogates aren't valid for UTF-32 characters, so define some
-// constants that will let us screen them out.
-static const char32_t kUnicodeSurrogateHighStart = 0x0000D800;
-static const char32_t kUnicodeSurrogateHighEnd = 0x0000DBFF;
-static const char32_t kUnicodeSurrogateLowStart = 0x0000DC00;
-static const char32_t kUnicodeSurrogateLowEnd = 0x0000DFFF;
-static const char32_t kUnicodeSurrogateStart = kUnicodeSurrogateHighStart;
-static const char32_t kUnicodeSurrogateEnd = kUnicodeSurrogateLowEnd;
-static const char32_t kUnicodeMaxCodepoint = 0x0010FFFF;
-
-// Mask used to set appropriate bits in first byte of UTF-8 sequence,
-// indexed by number of bytes in the sequence.
-// 0xxxxxxx
-// -> (00-7f) 7bit. Bit mask for the first byte is 0x00000000
-// 110yyyyx 10xxxxxx
-// -> (c0-df)(80-bf) 11bit. Bit mask is 0x000000C0
-// 1110yyyy 10yxxxxx 10xxxxxx
-// -> (e0-ef)(80-bf)(80-bf) 16bit. Bit mask is 0x000000E0
-// 11110yyy 10yyxxxx 10xxxxxx 10xxxxxx
-// -> (f0-f7)(80-bf)(80-bf)(80-bf) 21bit. Bit mask is 0x000000F0
-static const char32_t kFirstByteMark[] = {
- 0x00000000, 0x00000000, 0x000000C0, 0x000000E0, 0x000000F0
-};
-
// Separator used by resource paths. This is not platform dependent contrary
// to OS_PATH_SEPARATOR.
#define RES_PATH_SEPARATOR '/'
-// Return number of utf8 bytes required for the character.
-static size_t utf32_to_utf8_bytes(char32_t srcChar)
-{
- size_t bytesToWrite;
-
- // Figure out how many bytes the result will require.
- if (srcChar < 0x00000080)
- {
- bytesToWrite = 1;
- }
- else if (srcChar < 0x00000800)
- {
- bytesToWrite = 2;
- }
- else if (srcChar < 0x00010000)
- {
- if ((srcChar < kUnicodeSurrogateStart)
- || (srcChar > kUnicodeSurrogateEnd))
- {
- bytesToWrite = 3;
- }
- else
- {
- // Surrogates are invalid UTF-32 characters.
- return 0;
- }
- }
- // Max code point for Unicode is 0x0010FFFF.
- else if (srcChar <= kUnicodeMaxCodepoint)
- {
- bytesToWrite = 4;
- }
- else
- {
- // Invalid UTF-32 character.
- return 0;
- }
-
- return bytesToWrite;
-}
-
-// Write out the source character to <dstP>.
-
-static void utf32_to_utf8(uint8_t* dstP, char32_t srcChar, size_t bytes)
-{
- dstP += bytes;
- switch (bytes)
- { /* note: everything falls through. */
- case 4: *--dstP = (uint8_t)((srcChar | kByteMark) & kByteMask); srcChar >>= 6;
- case 3: *--dstP = (uint8_t)((srcChar | kByteMark) & kByteMask); srcChar >>= 6;
- case 2: *--dstP = (uint8_t)((srcChar | kByteMark) & kByteMask); srcChar >>= 6;
- case 1: *--dstP = (uint8_t)(srcChar | kFirstByteMark[bytes]);
- }
-}
-
-// ---------------------------------------------------------------------------
-
static SharedBuffer* gEmptyStringBuf = NULL;
static char* gEmptyString = NULL;
@@ -175,62 +93,47 @@
return getEmptyString();
}
-template<typename T, typename L>
-static char* allocFromUTF16OrUTF32(const T* in, L len)
-{
- if (len == 0) return getEmptyString();
-
- size_t bytes = 0;
- const T* end = in+len;
- const T* p = in;
-
- while (p < end) {
- bytes += utf32_to_utf8_bytes(*p);
- p++;
- }
-
- SharedBuffer* buf = SharedBuffer::alloc(bytes+1);
- LOG_ASSERT(buf, "Unable to allocate shared buffer");
- if (buf) {
- p = in;
- char* str = (char*)buf->data();
- char* d = str;
- while (p < end) {
- const T c = *p++;
- size_t len = utf32_to_utf8_bytes(c);
- utf32_to_utf8((uint8_t*)d, c, len);
- d += len;
- }
- *d = 0;
-
- return str;
- }
-
- return getEmptyString();
-}
-
static char* allocFromUTF16(const char16_t* in, size_t len)
{
if (len == 0) return getEmptyString();
- const size_t bytes = utf8_length_from_utf16(in, len);
+ const ssize_t bytes = utf16_to_utf8_length(in, len);
+ if (bytes < 0) {
+ return getEmptyString();
+ }
SharedBuffer* buf = SharedBuffer::alloc(bytes+1);
LOG_ASSERT(buf, "Unable to allocate shared buffer");
- if (buf) {
- char* str = (char*)buf->data();
-
- utf16_to_utf8(in, len, str, bytes+1);
-
- return str;
+ if (!buf) {
+ return getEmptyString();
}
- return getEmptyString();
+ char* str = (char*)buf->data();
+ utf16_to_utf8(in, len, str);
+ return str;
}
static char* allocFromUTF32(const char32_t* in, size_t len)
{
- return allocFromUTF16OrUTF32<char32_t, size_t>(in, len);
+ if (len == 0) {
+ return getEmptyString();
+ }
+
+ const ssize_t bytes = utf32_to_utf8_length(in, len);
+ if (bytes < 0) {
+ return getEmptyString();
+ }
+
+ SharedBuffer* buf = SharedBuffer::alloc(bytes+1);
+ LOG_ASSERT(buf, "Unable to allocate shared buffer");
+ if (!buf) {
+ return getEmptyString();
+ }
+
+ char* str = (char*) buf->data();
+ utf32_to_utf8(in, len, str);
+
+ return str;
}
// ---------------------------------------------------------------------------
@@ -510,17 +413,17 @@
size_t String8::getUtf32Length() const
{
- return utf32_length(mString, length());
+ return utf8_to_utf32_length(mString, length());
}
int32_t String8::getUtf32At(size_t index, size_t *next_index) const
{
- return utf32_at(mString, length(), index, next_index);
+ return utf32_from_utf8_at(mString, length(), index, next_index);
}
-size_t String8::getUtf32(char32_t* dst, size_t dst_len) const
+void String8::getUtf32(char32_t* dst) const
{
- return utf8_to_utf32(mString, length(), dst, dst_len);
+ utf8_to_utf32(mString, length(), dst);
}
TextOutput& operator<<(TextOutput& to, const String8& val)
@@ -705,241 +608,3 @@
}
}; // namespace android
-
-// ---------------------------------------------------------------------------
-
-size_t strlen32(const char32_t *s)
-{
- const char32_t *ss = s;
- while ( *ss )
- ss++;
- return ss-s;
-}
-
-size_t strnlen32(const char32_t *s, size_t maxlen)
-{
- const char32_t *ss = s;
- while ((maxlen > 0) && *ss) {
- ss++;
- maxlen--;
- }
- return ss-s;
-}
-
-size_t utf8_length(const char *src)
-{
- const char *cur = src;
- size_t ret = 0;
- while (*cur != '\0') {
- const char first_char = *cur++;
- if ((first_char & 0x80) == 0) { // ASCII
- ret += 1;
- continue;
- }
- // (UTF-8's character must not be like 10xxxxxx,
- // but 110xxxxx, 1110xxxx, ... or 1111110x)
- if ((first_char & 0x40) == 0) {
- return 0;
- }
-
- int32_t mask, to_ignore_mask;
- size_t num_to_read = 0;
- char32_t utf32 = 0;
- for (num_to_read = 1, mask = 0x40, to_ignore_mask = 0x80;
- num_to_read < 5 && (first_char & mask);
- num_to_read++, to_ignore_mask |= mask, mask >>= 1) {
- if ((*cur & 0xC0) != 0x80) { // must be 10xxxxxx
- return 0;
- }
- // 0x3F == 00111111
- utf32 = (utf32 << 6) + (*cur++ & 0x3F);
- }
- // "first_char" must be (110xxxxx - 11110xxx)
- if (num_to_read == 5) {
- return 0;
- }
- to_ignore_mask |= mask;
- utf32 |= ((~to_ignore_mask) & first_char) << (6 * (num_to_read - 1));
- if (utf32 > android::kUnicodeMaxCodepoint) {
- return 0;
- }
-
- ret += num_to_read;
- }
- return ret;
-}
-
-size_t utf32_length(const char *src, size_t src_len)
-{
- if (src == NULL || src_len == 0) {
- return 0;
- }
- size_t ret = 0;
- const char* cur;
- const char* end;
- size_t num_to_skip;
- for (cur = src, end = src + src_len, num_to_skip = 1;
- cur < end;
- cur += num_to_skip, ret++) {
- const char first_char = *cur;
- num_to_skip = 1;
- if ((first_char & 0x80) == 0) { // ASCII
- continue;
- }
- int32_t mask;
-
- for (mask = 0x40; (first_char & mask); num_to_skip++, mask >>= 1) {
- }
- }
- return ret;
-}
-
-size_t utf8_length_from_utf32(const char32_t *src, size_t src_len)
-{
- if (src == NULL || src_len == 0) {
- return 0;
- }
- size_t ret = 0;
- const char32_t *end = src + src_len;
- while (src < end) {
- ret += android::utf32_to_utf8_bytes(*src++);
- }
- return ret;
-}
-
-size_t utf8_length_from_utf16(const char16_t *src, size_t src_len)
-{
- if (src == NULL || src_len == 0) {
- return 0;
- }
- size_t ret = 0;
- const char16_t* const end = src + src_len;
- while (src < end) {
- if ((*src & 0xFC00) == 0xD800 && (src + 1) < end
- && (*++src & 0xFC00) == 0xDC00) {
- // surrogate pairs are always 4 bytes.
- ret += 4;
- src++;
- } else {
- ret += android::utf32_to_utf8_bytes((char32_t) *src++);
- }
- }
- return ret;
-}
-
-static int32_t utf32_at_internal(const char* cur, size_t *num_read)
-{
- const char first_char = *cur;
- if ((first_char & 0x80) == 0) { // ASCII
- *num_read = 1;
- return *cur;
- }
- cur++;
- char32_t mask, to_ignore_mask;
- size_t num_to_read = 0;
- char32_t utf32 = first_char;
- for (num_to_read = 1, mask = 0x40, to_ignore_mask = 0xFFFFFF80;
- (first_char & mask);
- num_to_read++, to_ignore_mask |= mask, mask >>= 1) {
- // 0x3F == 00111111
- utf32 = (utf32 << 6) + (*cur++ & 0x3F);
- }
- to_ignore_mask |= mask;
- utf32 &= ~(to_ignore_mask << (6 * (num_to_read - 1)));
-
- *num_read = num_to_read;
- return static_cast<int32_t>(utf32);
-}
-
-int32_t utf32_at(const char *src, size_t src_len,
- size_t index, size_t *next_index)
-{
- if (index >= src_len) {
- return -1;
- }
- size_t dummy_index;
- if (next_index == NULL) {
- next_index = &dummy_index;
- }
- size_t num_read;
- int32_t ret = utf32_at_internal(src + index, &num_read);
- if (ret >= 0) {
- *next_index = index + num_read;
- }
-
- return ret;
-}
-
-size_t utf8_to_utf32(const char* src, size_t src_len,
- char32_t* dst, size_t dst_len)
-{
- if (src == NULL || src_len == 0 || dst == NULL || dst_len == 0) {
- return 0;
- }
-
- const char* cur = src;
- const char* end = src + src_len;
- char32_t* cur_utf32 = dst;
- const char32_t* end_utf32 = dst + dst_len;
- while (cur_utf32 < end_utf32 && cur < end) {
- size_t num_read;
- *cur_utf32++ =
- static_cast<char32_t>(utf32_at_internal(cur, &num_read));
- cur += num_read;
- }
- if (cur_utf32 < end_utf32) {
- *cur_utf32 = 0;
- }
- return static_cast<size_t>(cur_utf32 - dst);
-}
-
-size_t utf32_to_utf8(const char32_t* src, size_t src_len,
- char* dst, size_t dst_len)
-{
- if (src == NULL || src_len == 0 || dst == NULL || dst_len == 0) {
- return 0;
- }
- const char32_t *cur_utf32 = src;
- const char32_t *end_utf32 = src + src_len;
- char *cur = dst;
- const char *end = dst + dst_len;
- while (cur_utf32 < end_utf32 && cur < end) {
- size_t len = android::utf32_to_utf8_bytes(*cur_utf32);
- android::utf32_to_utf8((uint8_t *)cur, *cur_utf32++, len);
- cur += len;
- }
- if (cur < end) {
- *cur = '\0';
- }
- return cur - dst;
-}
-
-size_t utf16_to_utf8(const char16_t* src, size_t src_len,
- char* dst, size_t dst_len)
-{
- if (src == NULL || src_len == 0 || dst == NULL || dst_len == 0) {
- return 0;
- }
- const char16_t* cur_utf16 = src;
- const char16_t* const end_utf16 = src + src_len;
- char *cur = dst;
- const char* const end = dst + dst_len;
- while (cur_utf16 < end_utf16 && cur < end) {
- char32_t utf32;
- // surrogate pairs
- if ((*cur_utf16 & 0xFC00) == 0xD800 && (cur_utf16 + 1) < end_utf16) {
- utf32 = (*cur_utf16++ - 0xD800) << 10;
- utf32 |= *cur_utf16++ - 0xDC00;
- utf32 += 0x10000;
- } else {
- utf32 = (char32_t) *cur_utf16++;
- }
- size_t len = android::utf32_to_utf8_bytes(utf32);
- android::utf32_to_utf8((uint8_t*)cur, utf32, len);
- cur += len;
- }
- if (cur < end) {
- *cur = '\0';
- }
- return cur - dst;
-}
diff --git a/libs/utils/Unicode.cpp b/libs/utils/Unicode.cpp
new file mode 100644
index 0000000..78c61b4
--- /dev/null
+++ b/libs/utils/Unicode.cpp
@@ -0,0 +1,575 @@
+/*
+ * Copyright (C) 2005 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 <utils/Unicode.h>
+
+#include <stddef.h>
+
+#ifdef HAVE_WINSOCK
+# undef nhtol
+# undef htonl
+# undef nhtos
+# undef htons
+
+# ifdef HAVE_LITTLE_ENDIAN
+# define ntohl(x) ( ((x) << 24) | (((x) >> 24) & 255) | (((x) << 8) & 0xff0000) | (((x) >> 8) & 0xff00) )
+# define htonl(x) ntohl(x)
+# define ntohs(x) ( (((x) << 8) & 0xff00) | (((x) >> 8) & 255) )
+# define htons(x) ntohs(x)
+# else
+# define ntohl(x) (x)
+# define htonl(x) (x)
+# define ntohs(x) (x)
+# define htons(x) (x)
+# endif
+#else
+# include <netinet/in.h>
+#endif
+
+extern "C" {
+
+static const char32_t kByteMask = 0x000000BF;
+static const char32_t kByteMark = 0x00000080;
+
+// Surrogates aren't valid for UTF-32 characters, so define some
+// constants that will let us screen them out.
+static const char32_t kUnicodeSurrogateHighStart = 0x0000D800;
+static const char32_t kUnicodeSurrogateHighEnd = 0x0000DBFF;
+static const char32_t kUnicodeSurrogateLowStart = 0x0000DC00;
+static const char32_t kUnicodeSurrogateLowEnd = 0x0000DFFF;
+static const char32_t kUnicodeSurrogateStart = kUnicodeSurrogateHighStart;
+static const char32_t kUnicodeSurrogateEnd = kUnicodeSurrogateLowEnd;
+static const char32_t kUnicodeMaxCodepoint = 0x0010FFFF;
+
+// Mask used to set appropriate bits in first byte of UTF-8 sequence,
+// indexed by number of bytes in the sequence.
+// 0xxxxxxx
+// -> (00-7f) 7bit. Bit mask for the first byte is 0x00000000
+// 110yyyyx 10xxxxxx
+// -> (c0-df)(80-bf) 11bit. Bit mask is 0x000000C0
+// 1110yyyy 10yxxxxx 10xxxxxx
+// -> (e0-ef)(80-bf)(80-bf) 16bit. Bit mask is 0x000000E0
+// 11110yyy 10yyxxxx 10xxxxxx 10xxxxxx
+// -> (f0-f7)(80-bf)(80-bf)(80-bf) 21bit. Bit mask is 0x000000F0
+static const char32_t kFirstByteMark[] = {
+ 0x00000000, 0x00000000, 0x000000C0, 0x000000E0, 0x000000F0
+};
+
+// --------------------------------------------------------------------------
+// UTF-32
+// --------------------------------------------------------------------------
+
+/**
+ * Return number of UTF-8 bytes required for the character. If the character
+ * is invalid, return size of 0.
+ */
+static inline size_t utf32_codepoint_utf8_length(char32_t srcChar)
+{
+ // Figure out how many bytes the result will require.
+ if (srcChar < 0x00000080) {
+ return 1;
+ } else if (srcChar < 0x00000800) {
+ return 2;
+ } else if (srcChar < 0x00010000) {
+ if ((srcChar < kUnicodeSurrogateStart) || (srcChar > kUnicodeSurrogateEnd)) {
+ return 3;
+ } else {
+ // Surrogates are invalid UTF-32 characters.
+ return 0;
+ }
+ }
+ // Max code point for Unicode is 0x0010FFFF.
+ else if (srcChar <= kUnicodeMaxCodepoint) {
+ return 4;
+ } else {
+ // Invalid UTF-32 character.
+ return 0;
+ }
+}
+
+// Write out the source character to <dstP>.
+
+static inline void utf32_codepoint_to_utf8(uint8_t* dstP, char32_t srcChar, size_t bytes)
+{
+ dstP += bytes;
+ switch (bytes)
+ { /* note: everything falls through. */
+ case 4: *--dstP = (uint8_t)((srcChar | kByteMark) & kByteMask); srcChar >>= 6;
+ case 3: *--dstP = (uint8_t)((srcChar | kByteMark) & kByteMask); srcChar >>= 6;
+ case 2: *--dstP = (uint8_t)((srcChar | kByteMark) & kByteMask); srcChar >>= 6;
+ case 1: *--dstP = (uint8_t)(srcChar | kFirstByteMark[bytes]);
+ }
+}
+
+size_t strlen32(const char32_t *s)
+{
+ const char32_t *ss = s;
+ while ( *ss )
+ ss++;
+ return ss-s;
+}
+
+size_t strnlen32(const char32_t *s, size_t maxlen)
+{
+ const char32_t *ss = s;
+ while ((maxlen > 0) && *ss) {
+ ss++;
+ maxlen--;
+ }
+ return ss-s;
+}
+
+static inline int32_t utf32_at_internal(const char* cur, size_t *num_read)
+{
+ const char first_char = *cur;
+ if ((first_char & 0x80) == 0) { // ASCII
+ *num_read = 1;
+ return *cur;
+ }
+ cur++;
+ char32_t mask, to_ignore_mask;
+ size_t num_to_read = 0;
+ char32_t utf32 = first_char;
+ for (num_to_read = 1, mask = 0x40, to_ignore_mask = 0xFFFFFF80;
+ (first_char & mask);
+ num_to_read++, to_ignore_mask |= mask, mask >>= 1) {
+ // 0x3F == 00111111
+ utf32 = (utf32 << 6) + (*cur++ & 0x3F);
+ }
+ to_ignore_mask |= mask;
+ utf32 &= ~(to_ignore_mask << (6 * (num_to_read - 1)));
+
+ *num_read = num_to_read;
+ return static_cast<int32_t>(utf32);
+}
+
+int32_t utf32_from_utf8_at(const char *src, size_t src_len, size_t index, size_t *next_index)
+{
+ if (index >= src_len) {
+ return -1;
+ }
+ size_t dummy_index;
+ if (next_index == NULL) {
+ next_index = &dummy_index;
+ }
+ size_t num_read;
+ int32_t ret = utf32_at_internal(src + index, &num_read);
+ if (ret >= 0) {
+ *next_index = index + num_read;
+ }
+
+ return ret;
+}
+
+ssize_t utf32_to_utf8_length(const char32_t *src, size_t src_len)
+{
+ if (src == NULL || src_len == 0) {
+ return -1;
+ }
+
+ size_t ret = 0;
+ const char32_t *end = src + src_len;
+ while (src < end) {
+ ret += utf32_codepoint_utf8_length(*src++);
+ }
+ return ret;
+}
+
+void utf32_to_utf8(const char32_t* src, size_t src_len, char* dst)
+{
+ if (src == NULL || src_len == 0 || dst == NULL) {
+ return;
+ }
+
+ const char32_t *cur_utf32 = src;
+ const char32_t *end_utf32 = src + src_len;
+ char *cur = dst;
+ while (cur_utf32 < end_utf32) {
+ size_t len = utf32_codepoint_utf8_length(*cur_utf32);
+ utf32_codepoint_to_utf8((uint8_t *)cur, *cur_utf32++, len);
+ cur += len;
+ }
+ *cur = '\0';
+}
+
+// --------------------------------------------------------------------------
+// UTF-16
+// --------------------------------------------------------------------------
+
+int strcmp16(const char16_t *s1, const char16_t *s2)
+{
+ char16_t ch;
+ int d = 0;
+
+ while ( 1 ) {
+ d = (int)(ch = *s1++) - (int)*s2++;
+ if ( d || !ch )
+ break;
+ }
+
+ return d;
+}
+
+int strncmp16(const char16_t *s1, const char16_t *s2, size_t n)
+{
+ char16_t ch;
+ int d = 0;
+
+ while ( n-- ) {
+ d = (int)(ch = *s1++) - (int)*s2++;
+ if ( d || !ch )
+ break;
+ }
+
+ return d;
+}
+
+char16_t *strcpy16(char16_t *dst, const char16_t *src)
+{
+ char16_t *q = dst;
+ const char16_t *p = src;
+ char16_t ch;
+
+ do {
+ *q++ = ch = *p++;
+ } while ( ch );
+
+ return dst;
+}
+
+size_t strlen16(const char16_t *s)
+{
+ const char16_t *ss = s;
+ while ( *ss )
+ ss++;
+ return ss-s;
+}
+
+
+char16_t *strncpy16(char16_t *dst, const char16_t *src, size_t n)
+{
+ char16_t *q = dst;
+ const char16_t *p = src;
+ char ch;
+
+ while (n) {
+ n--;
+ *q++ = ch = *p++;
+ if ( !ch )
+ break;
+ }
+
+ *q = 0;
+
+ return dst;
+}
+
+size_t strnlen16(const char16_t *s, size_t maxlen)
+{
+ const char16_t *ss = s;
+
+ /* Important: the maxlen test must precede the reference through ss;
+ since the byte beyond the maximum may segfault */
+ while ((maxlen > 0) && *ss) {
+ ss++;
+ maxlen--;
+ }
+ return ss-s;
+}
+
+int strzcmp16(const char16_t *s1, size_t n1, const char16_t *s2, size_t n2)
+{
+ const char16_t* e1 = s1+n1;
+ const char16_t* e2 = s2+n2;
+
+ while (s1 < e1 && s2 < e2) {
+ const int d = (int)*s1++ - (int)*s2++;
+ if (d) {
+ return d;
+ }
+ }
+
+ return n1 < n2
+ ? (0 - (int)*s2)
+ : (n1 > n2
+ ? ((int)*s1 - 0)
+ : 0);
+}
+
+int strzcmp16_h_n(const char16_t *s1H, size_t n1, const char16_t *s2N, size_t n2)
+{
+ const char16_t* e1 = s1H+n1;
+ const char16_t* e2 = s2N+n2;
+
+ while (s1H < e1 && s2N < e2) {
+ const char16_t c2 = ntohs(*s2N);
+ const int d = (int)*s1H++ - (int)c2;
+ s2N++;
+ if (d) {
+ return d;
+ }
+ }
+
+ return n1 < n2
+ ? (0 - (int)ntohs(*s2N))
+ : (n1 > n2
+ ? ((int)*s1H - 0)
+ : 0);
+}
+
+void utf16_to_utf8(const char16_t* src, size_t src_len, char* dst)
+{
+ if (src == NULL || src_len == 0 || dst == NULL) {
+ return;
+ }
+
+ const char16_t* cur_utf16 = src;
+ const char16_t* const end_utf16 = src + src_len;
+ char *cur = dst;
+ while (cur_utf16 < end_utf16) {
+ char32_t utf32;
+ // surrogate pairs
+ if ((*cur_utf16 & 0xFC00) == 0xD800) {
+ utf32 = (*cur_utf16++ - 0xD800) << 10;
+ utf32 |= *cur_utf16++ - 0xDC00;
+ utf32 += 0x10000;
+ } else {
+ utf32 = (char32_t) *cur_utf16++;
+ }
+ const size_t len = utf32_codepoint_utf8_length(utf32);
+ utf32_codepoint_to_utf8((uint8_t*)cur, utf32, len);
+ cur += len;
+ }
+ *cur = '\0';
+}
+
+// --------------------------------------------------------------------------
+// UTF-8
+// --------------------------------------------------------------------------
+
+ssize_t utf8_length(const char *src)
+{
+ const char *cur = src;
+ size_t ret = 0;
+ while (*cur != '\0') {
+ const char first_char = *cur++;
+ if ((first_char & 0x80) == 0) { // ASCII
+ ret += 1;
+ continue;
+ }
+ // (UTF-8's character must not be like 10xxxxxx,
+ // but 110xxxxx, 1110xxxx, ... or 1111110x)
+ if ((first_char & 0x40) == 0) {
+ return -1;
+ }
+
+ int32_t mask, to_ignore_mask;
+ size_t num_to_read = 0;
+ char32_t utf32 = 0;
+ for (num_to_read = 1, mask = 0x40, to_ignore_mask = 0x80;
+ num_to_read < 5 && (first_char & mask);
+ num_to_read++, to_ignore_mask |= mask, mask >>= 1) {
+ if ((*cur & 0xC0) != 0x80) { // must be 10xxxxxx
+ return -1;
+ }
+ // 0x3F == 00111111
+ utf32 = (utf32 << 6) + (*cur++ & 0x3F);
+ }
+ // "first_char" must be (110xxxxx - 11110xxx)
+ if (num_to_read == 5) {
+ return -1;
+ }
+ to_ignore_mask |= mask;
+ utf32 |= ((~to_ignore_mask) & first_char) << (6 * (num_to_read - 1));
+ if (utf32 > kUnicodeMaxCodepoint) {
+ return -1;
+ }
+
+ ret += num_to_read;
+ }
+ return ret;
+}
+
+ssize_t utf16_to_utf8_length(const char16_t *src, size_t src_len)
+{
+ if (src == NULL || src_len == 0) {
+ return -1;
+ }
+
+ size_t ret = 0;
+ const char16_t* const end = src + src_len;
+ while (src < end) {
+ if ((*src & 0xFC00) == 0xD800 && (src + 1) < end
+ && (*++src & 0xFC00) == 0xDC00) {
+ // surrogate pairs are always 4 bytes.
+ ret += 4;
+ src++;
+ } else {
+ ret += utf32_codepoint_utf8_length((char32_t) *src++);
+ }
+ }
+ return ret;
+}
+
+/**
+ * Returns 1-4 based on the number of leading bits.
+ *
+ * 1111 -> 4
+ * 1110 -> 3
+ * 110x -> 2
+ * 10xx -> 1
+ * 0xxx -> 1
+ */
+static inline size_t utf8_codepoint_len(uint8_t ch)
+{
+ return ((0xe5000000 >> ((ch >> 3) & 0x1e)) & 3) + 1;
+}
+
+static inline void utf8_shift_and_mask(uint32_t* codePoint, const uint8_t byte)
+{
+ *codePoint <<= 6;
+ *codePoint |= 0x3F & byte;
+}
+
+size_t utf8_to_utf32_length(const char *src, size_t src_len)
+{
+ if (src == NULL || src_len == 0) {
+ return 0;
+ }
+ size_t ret = 0;
+ const char* cur;
+ const char* end;
+ size_t num_to_skip;
+ for (cur = src, end = src + src_len, num_to_skip = 1;
+ cur < end;
+ cur += num_to_skip, ret++) {
+ const char first_char = *cur;
+ num_to_skip = 1;
+ if ((first_char & 0x80) == 0) { // ASCII
+ continue;
+ }
+ int32_t mask;
+
+ for (mask = 0x40; (first_char & mask); num_to_skip++, mask >>= 1) {
+ }
+ }
+ return ret;
+}
+
+void utf8_to_utf32(const char* src, size_t src_len, char32_t* dst)
+{
+ if (src == NULL || src_len == 0 || dst == NULL) {
+ return;
+ }
+
+ const char* cur = src;
+ const char* const end = src + src_len;
+ char32_t* cur_utf32 = dst;
+ while (cur < end) {
+ size_t num_read;
+ *cur_utf32++ = static_cast<char32_t>(utf32_at_internal(cur, &num_read));
+ cur += num_read;
+ }
+ *cur_utf32 = 0;
+}
+
+static inline uint32_t utf8_to_utf32_codepoint(const uint8_t *src, size_t length)
+{
+ uint32_t unicode;
+
+ switch (length)
+ {
+ case 1:
+ return src[0];
+ case 2:
+ unicode = src[0] & 0x1f;
+ utf8_shift_and_mask(&unicode, src[1]);
+ return unicode;
+ case 3:
+ unicode = src[0] & 0x0f;
+ utf8_shift_and_mask(&unicode, src[1]);
+ utf8_shift_and_mask(&unicode, src[2]);
+ return unicode;
+ case 4:
+ unicode = src[0] & 0x07;
+ utf8_shift_and_mask(&unicode, src[1]);
+ utf8_shift_and_mask(&unicode, src[2]);
+ utf8_shift_and_mask(&unicode, src[3]);
+ return unicode;
+ default:
+ return 0xffff;
+ }
+
+ //printf("Char at %p: len=%d, utf-16=%p\n", src, length, (void*)result);
+}
+
+ssize_t utf8_to_utf16_length(const uint8_t* u8str, size_t u8len)
+{
+ const uint8_t* const u8end = u8str + u8len;
+ const uint8_t* u8cur = u8str;
+
+ /* Validate that the UTF-8 is the correct len */
+ size_t u16measuredLen = 0;
+ while (u8cur < u8end) {
+ u16measuredLen++;
+ int u8charLen = utf8_codepoint_len(*u8cur);
+ uint32_t codepoint = utf8_to_utf32_codepoint(u8cur, u8charLen);
+ if (codepoint > 0xFFFF) u16measuredLen++; // this will be a surrogate pair in utf16
+ u8cur += u8charLen;
+ }
+
+ /**
+ * Make sure that we ended where we thought we would and the output UTF-16
+ * will be exactly how long we were told it would be.
+ */
+ if (u8cur != u8end) {
+ return -1;
+ }
+
+ return u16measuredLen;
+}
+
+/**
+ * Convert a UTF-8 string to UTF-16. The destination UTF-16 buffer must have
+ * space for NULL at the end.
+ */
+void utf8_to_utf16(const uint8_t* u8str, size_t u8len, char16_t* u16str)
+{
+ const uint8_t* const u8end = u8str + u8len;
+ const uint8_t* u8cur = u8str;
+ char16_t* u16cur = u16str;
+
+ while (u8cur < u8end) {
+ size_t u8len = utf8_codepoint_len(*u8cur);
+ uint32_t codepoint = utf8_to_utf32_codepoint(u8cur, u8len);
+
+ // Convert the UTF32 codepoint to one or more UTF16 codepoints
+ if (codepoint <= 0xFFFF) {
+ // Single UTF16 character
+ *u16cur++ = (char16_t) codepoint;
+ } else {
+ // Multiple UTF16 characters with surrogates
+ codepoint = codepoint - 0x10000;
+ *u16cur++ = (char16_t) ((codepoint >> 10) + 0xD800);
+ *u16cur++ = (char16_t) ((codepoint & 0x3FF) + 0xDC00);
+ }
+
+ u8cur += u8len;
+ }
+ *u16cur = 0;
+}
+
+}
diff --git a/libs/utils/tests/Android.mk b/libs/utils/tests/Android.mk
index 00077ee..72d4876 100644
--- a/libs/utils/tests/Android.mk
+++ b/libs/utils/tests/Android.mk
@@ -8,7 +8,8 @@
test_src_files := \
ObbFile_test.cpp \
Looper_test.cpp \
- String8_test.cpp
+ String8_test.cpp \
+ Unicode_test.cpp
shared_libraries := \
libz \
diff --git a/libs/utils/tests/Unicode_test.cpp b/libs/utils/tests/Unicode_test.cpp
new file mode 100644
index 0000000..18c130c
--- /dev/null
+++ b/libs/utils/tests/Unicode_test.cpp
@@ -0,0 +1,115 @@
+/*
+ * 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.
+ */
+
+#define LOG_TAG "Unicode_test"
+#include <utils/Log.h>
+#include <utils/Unicode.h>
+
+#include <gtest/gtest.h>
+
+namespace android {
+
+class UnicodeTest : public testing::Test {
+protected:
+ virtual void SetUp() {
+ }
+
+ virtual void TearDown() {
+ }
+};
+
+TEST_F(UnicodeTest, UTF8toUTF16ZeroLength) {
+ ssize_t measured;
+
+ const uint8_t str[] = { };
+
+ measured = utf8_to_utf16_length(str, 0);
+ EXPECT_EQ(0, measured)
+ << "Zero length input should return zero length output.";
+}
+
+TEST_F(UnicodeTest, UTF8toUTF16ASCIILength) {
+ ssize_t measured;
+
+ // U+0030 or ASCII '0'
+ const uint8_t str[] = { 0x30 };
+
+ measured = utf8_to_utf16_length(str, sizeof(str));
+ EXPECT_EQ(1, measured)
+ << "ASCII glyphs should have a length of 1 char16_t";
+}
+
+TEST_F(UnicodeTest, UTF8toUTF16Plane1Length) {
+ ssize_t measured;
+
+ // U+2323 SMILE
+ const uint8_t str[] = { 0xE2, 0x8C, 0xA3 };
+
+ measured = utf8_to_utf16_length(str, sizeof(str));
+ EXPECT_EQ(1, measured)
+ << "Plane 1 glyphs should have a length of 1 char16_t";
+}
+
+TEST_F(UnicodeTest, UTF8toUTF16SurrogateLength) {
+ ssize_t measured;
+
+ // U+10000
+ const uint8_t str[] = { 0xF0, 0x90, 0x80, 0x80 };
+
+ measured = utf8_to_utf16_length(str, sizeof(str));
+ EXPECT_EQ(2, measured)
+ << "Surrogate pairs should have a length of 2 char16_t";
+}
+
+TEST_F(UnicodeTest, UTF8toUTF16TruncatedUTF8) {
+ ssize_t measured;
+
+ // Truncated U+2323 SMILE
+ // U+2323 SMILE
+ const uint8_t str[] = { 0xE2, 0x8C };
+
+ measured = utf8_to_utf16_length(str, sizeof(str));
+ EXPECT_EQ(-1, measured)
+ << "Truncated UTF-8 should return -1 to indicate invalid";
+}
+
+TEST_F(UnicodeTest, UTF8toUTF16Normal) {
+ const uint8_t str[] = {
+ 0x30, // U+0030, 1 UTF-16 character
+ 0xC4, 0x80, // U+0100, 1 UTF-16 character
+ 0xE2, 0x8C, 0xA3, // U+2323, 1 UTF-16 character
+ 0xF0, 0x90, 0x80, 0x80, // U+10000, 2 UTF-16 character
+ };
+
+ char16_t output[1 + 1 + 1 + 2 + 1]; // Room for NULL
+
+ utf8_to_utf16(str, sizeof(str), output);
+
+ EXPECT_EQ(0x0030, output[0])
+ << "should be U+0030";
+ EXPECT_EQ(0x0100, output[1])
+ << "should be U+0100";
+ EXPECT_EQ(0x2323, output[2])
+ << "should be U+2323";
+ EXPECT_EQ(0xD800, output[3])
+ << "should be first half of surrogate U+10000";
+ EXPECT_EQ(0xDC00, output[4])
+ << "should be second half of surrogate U+10000";
+ EXPECT_EQ(NULL, output[5])
+ << "should be NULL terminated";
+}
+
+}
diff --git a/media/java/android/media/MtpDatabase.java b/media/java/android/media/MtpDatabase.java
index 0d09d4c..42d068f 100644
--- a/media/java/android/media/MtpDatabase.java
+++ b/media/java/android/media/MtpDatabase.java
@@ -30,7 +30,6 @@
import android.provider.MediaStore.Images;
import android.provider.MediaStore.MediaColumns;
import android.provider.Mtp;
-import android.text.format.Time;
import android.util.Log;
import java.io.File;
@@ -504,14 +503,6 @@
return path.substring(start, end);
}
- private String formatDateTime(long seconds) {
- Time time = new Time(Time.TIMEZONE_UTC);
- time.set(seconds * 1000);
- String result = time.format("%Y-%m-%dT%H:%M:%SZ");
- Log.d(TAG, "formatDateTime returning " + result);
- return result;
- }
-
private MtpPropertyList getObjectPropertyList(int handle, int format, int property,
int groupCode, int depth) {
// FIXME - implement group support
@@ -683,7 +674,7 @@
case MtpConstants.PROPERTY_DATE_MODIFIED:
case MtpConstants.PROPERTY_DATE_ADDED:
// convert from seconds to DateTime
- result.setProperty(index, handle, property, formatDateTime(c.getInt(1)));
+ result.setProperty(index, handle, property, format_date_time(c.getInt(1)));
break;
case MtpConstants.PROPERTY_ORIGINAL_RELEASE_DATE:
// release date is stored internally as just the year
@@ -1029,4 +1020,5 @@
private native final void native_setup();
private native final void native_finalize();
+ private native String format_date_time(long seconds);
}
diff --git a/media/jni/android_media_MtpDatabase.cpp b/media/jni/android_media_MtpDatabase.cpp
index aa29de8..5377af6 100644
--- a/media/jni/android_media_MtpDatabase.cpp
+++ b/media/jni/android_media_MtpDatabase.cpp
@@ -1037,11 +1037,25 @@
#endif
}
+static jstring
+android_media_MtpDatabase_format_date_time(JNIEnv *env, jobject thiz, jlong seconds)
+{
+#ifdef HAVE_ANDROID_OS
+ char date[20];
+ formatDateTime(seconds, date, sizeof(date));
+ return env->NewStringUTF(date);
+#else
+ return NULL;
+#endif
+}
+
// ----------------------------------------------------------------------------
static JNINativeMethod gMethods[] = {
{"native_setup", "()V", (void *)android_media_MtpDatabase_setup},
{"native_finalize", "()V", (void *)android_media_MtpDatabase_finalize},
+ {"format_date_time", "(J)Ljava/lang/String;",
+ (void *)android_media_MtpDatabase_format_date_time},
};
static const char* const kClassPathName = "android/media/MtpDatabase";
diff --git a/media/libstagefright/CameraSource.cpp b/media/libstagefright/CameraSource.cpp
index b8450fb..d9ff723 100644
--- a/media/libstagefright/CameraSource.cpp
+++ b/media/libstagefright/CameraSource.cpp
@@ -495,26 +495,6 @@
mIsMetaDataStoredInVideoBuffers = true;
}
- /*
- * mCamera->startRecording() signals camera hal to make
- * available the video buffers (for instance, allocation
- * of the video buffers may be triggered when camera hal's
- * startRecording() method is called). Making available these
- * video buffers earlier (before calling start()) is critical,
- * if one wants to configure omx video encoders to use these
- * buffers for passing video frame data during video recording
- * without the need to memcpy the video frame data stored
- * in these buffers. Eliminating memcpy for video frame data
- * is crucial in performance for HD quality video recording
- * applications.
- *
- * Based on OMX IL spec, configuring the omx video encoders
- * must occur in loaded state. When start() is called, omx
- * video encoders are already in idle state, which is too
- * late. Thus, we must call mCamera->startRecording() earlier.
- */
- startCameraRecording();
-
IPCThreadState::self()->restoreCallingIdentity(token);
int64_t glitchDurationUs = (1000000LL / mVideoFrameRate);
@@ -565,8 +545,11 @@
mStartTimeUs = startTimeUs;
}
+ // Call setListener first before calling startCameraRecording()
+ // to avoid recording frames being dropped.
int64_t token = IPCThreadState::self()->clearCallingIdentity();
mCamera->setListener(new CameraSourceListener(this));
+ startCameraRecording();
IPCThreadState::self()->restoreCallingIdentity(token);
mStarted = true;
diff --git a/packages/SystemUI/res/anim/navigation_in.xml b/packages/SystemUI/res/anim/navigation_in.xml
deleted file mode 100644
index 630fd72..0000000
--- a/packages/SystemUI/res/anim/navigation_in.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- 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.
--->
-
-<set xmlns:android="http://schemas.android.com/apk/res/android"
- >
- <alpha android:fromAlpha="0.0" android:toAlpha="1.0"
- android:duration="@android:integer/config_longAnimTime"
- />
-</set>
diff --git a/packages/SystemUI/res/anim/navigation_out.xml b/packages/SystemUI/res/anim/navigation_out.xml
deleted file mode 100644
index 4717e47..0000000
--- a/packages/SystemUI/res/anim/navigation_out.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- 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.
--->
-
-<set xmlns:android="http://schemas.android.com/apk/res/android"
- >
- <alpha android:toAlpha="0.0" android:fromAlpha="1.0"
- android:duration="@android:integer/config_longAnimTime"
- />
-</set>
diff --git a/packages/SystemUI/res/drawable-hdpi/sysbar_battery_0.png b/packages/SystemUI/res/drawable-hdpi/sysbar_battery_0.png
deleted file mode 100644
index 35b765f..0000000
--- a/packages/SystemUI/res/drawable-hdpi/sysbar_battery_0.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/sysbar_battery_10.png b/packages/SystemUI/res/drawable-hdpi/sysbar_battery_10.png
deleted file mode 100644
index 39eeb06..0000000
--- a/packages/SystemUI/res/drawable-hdpi/sysbar_battery_10.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/sysbar_battery_100.png b/packages/SystemUI/res/drawable-hdpi/sysbar_battery_100.png
deleted file mode 100644
index b5787aa..0000000
--- a/packages/SystemUI/res/drawable-hdpi/sysbar_battery_100.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/sysbar_battery_20.png b/packages/SystemUI/res/drawable-hdpi/sysbar_battery_20.png
deleted file mode 100644
index 3fc2852..0000000
--- a/packages/SystemUI/res/drawable-hdpi/sysbar_battery_20.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/sysbar_battery_30.png b/packages/SystemUI/res/drawable-hdpi/sysbar_battery_30.png
deleted file mode 100644
index 6ba6da3..0000000
--- a/packages/SystemUI/res/drawable-hdpi/sysbar_battery_30.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/sysbar_battery_40.png b/packages/SystemUI/res/drawable-hdpi/sysbar_battery_40.png
deleted file mode 100644
index f5ac131..0000000
--- a/packages/SystemUI/res/drawable-hdpi/sysbar_battery_40.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/sysbar_battery_50.png b/packages/SystemUI/res/drawable-hdpi/sysbar_battery_50.png
deleted file mode 100644
index fffb701..0000000
--- a/packages/SystemUI/res/drawable-hdpi/sysbar_battery_50.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/sysbar_battery_60.png b/packages/SystemUI/res/drawable-hdpi/sysbar_battery_60.png
deleted file mode 100644
index 7b4fa44..0000000
--- a/packages/SystemUI/res/drawable-hdpi/sysbar_battery_60.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/sysbar_battery_70.png b/packages/SystemUI/res/drawable-hdpi/sysbar_battery_70.png
deleted file mode 100644
index 3c9eeb1..0000000
--- a/packages/SystemUI/res/drawable-hdpi/sysbar_battery_70.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/sysbar_battery_80.png b/packages/SystemUI/res/drawable-hdpi/sysbar_battery_80.png
deleted file mode 100644
index 3945188..0000000
--- a/packages/SystemUI/res/drawable-hdpi/sysbar_battery_80.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/sysbar_battery_90.png b/packages/SystemUI/res/drawable-hdpi/sysbar_battery_90.png
deleted file mode 100644
index 8a9241c..0000000
--- a/packages/SystemUI/res/drawable-hdpi/sysbar_battery_90.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/sysbar_batterymini_100.png b/packages/SystemUI/res/drawable-hdpi/sysbar_batterymini_100.png
deleted file mode 100644
index 67591fe..0000000
--- a/packages/SystemUI/res/drawable-hdpi/sysbar_batterymini_100.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/sysbar_batterymini_red.png b/packages/SystemUI/res/drawable-hdpi/sysbar_batterymini_red.png
deleted file mode 100644
index 697044b..0000000
--- a/packages/SystemUI/res/drawable-hdpi/sysbar_batterymini_red.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/sysbar_signalmini_100.png b/packages/SystemUI/res/drawable-hdpi/sysbar_signalmini_100.png
deleted file mode 100644
index 8bec533..0000000
--- a/packages/SystemUI/res/drawable-hdpi/sysbar_signalmini_100.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/sysbar_battery_0.png b/packages/SystemUI/res/drawable-mdpi/sysbar_battery_0.png
deleted file mode 100644
index ff75a51..0000000
--- a/packages/SystemUI/res/drawable-mdpi/sysbar_battery_0.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/sysbar_battery_10.png b/packages/SystemUI/res/drawable-mdpi/sysbar_battery_10.png
deleted file mode 100644
index 66ab4c6..0000000
--- a/packages/SystemUI/res/drawable-mdpi/sysbar_battery_10.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/sysbar_battery_100.png b/packages/SystemUI/res/drawable-mdpi/sysbar_battery_100.png
deleted file mode 100644
index 3b50500..0000000
--- a/packages/SystemUI/res/drawable-mdpi/sysbar_battery_100.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/sysbar_battery_20.png b/packages/SystemUI/res/drawable-mdpi/sysbar_battery_20.png
deleted file mode 100644
index 9119065..0000000
--- a/packages/SystemUI/res/drawable-mdpi/sysbar_battery_20.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/sysbar_battery_30.png b/packages/SystemUI/res/drawable-mdpi/sysbar_battery_30.png
deleted file mode 100644
index 296f19f26b..0000000
--- a/packages/SystemUI/res/drawable-mdpi/sysbar_battery_30.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/sysbar_battery_40.png b/packages/SystemUI/res/drawable-mdpi/sysbar_battery_40.png
deleted file mode 100644
index 9daab23..0000000
--- a/packages/SystemUI/res/drawable-mdpi/sysbar_battery_40.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/sysbar_battery_50.png b/packages/SystemUI/res/drawable-mdpi/sysbar_battery_50.png
deleted file mode 100644
index 62d24c4..0000000
--- a/packages/SystemUI/res/drawable-mdpi/sysbar_battery_50.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/sysbar_battery_60.png b/packages/SystemUI/res/drawable-mdpi/sysbar_battery_60.png
deleted file mode 100644
index eea927a..0000000
--- a/packages/SystemUI/res/drawable-mdpi/sysbar_battery_60.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/sysbar_battery_70.png b/packages/SystemUI/res/drawable-mdpi/sysbar_battery_70.png
deleted file mode 100644
index 6816088..0000000
--- a/packages/SystemUI/res/drawable-mdpi/sysbar_battery_70.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/sysbar_battery_80.png b/packages/SystemUI/res/drawable-mdpi/sysbar_battery_80.png
deleted file mode 100644
index b7dd9bb..0000000
--- a/packages/SystemUI/res/drawable-mdpi/sysbar_battery_80.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/sysbar_battery_90.png b/packages/SystemUI/res/drawable-mdpi/sysbar_battery_90.png
deleted file mode 100644
index 6e36f53..0000000
--- a/packages/SystemUI/res/drawable-mdpi/sysbar_battery_90.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/sysbar_batterymini_100.png b/packages/SystemUI/res/drawable-mdpi/sysbar_batterymini_100.png
deleted file mode 100644
index 8eb0f29..0000000
--- a/packages/SystemUI/res/drawable-mdpi/sysbar_batterymini_100.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/sysbar_batterymini_red.png b/packages/SystemUI/res/drawable-mdpi/sysbar_batterymini_red.png
deleted file mode 100644
index adcc6b9..0000000
--- a/packages/SystemUI/res/drawable-mdpi/sysbar_batterymini_red.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/sysbar_signal_0.png b/packages/SystemUI/res/drawable-mdpi/sysbar_signal_0.png
deleted file mode 100644
index 7469372..0000000
--- a/packages/SystemUI/res/drawable-mdpi/sysbar_signal_0.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/sysbar_signal_10.png b/packages/SystemUI/res/drawable-mdpi/sysbar_signal_10.png
deleted file mode 100644
index 6625d9a..0000000
--- a/packages/SystemUI/res/drawable-mdpi/sysbar_signal_10.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/sysbar_signal_100.png b/packages/SystemUI/res/drawable-mdpi/sysbar_signal_100.png
deleted file mode 100644
index b2e763b..0000000
--- a/packages/SystemUI/res/drawable-mdpi/sysbar_signal_100.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/sysbar_signal_20.png b/packages/SystemUI/res/drawable-mdpi/sysbar_signal_20.png
deleted file mode 100644
index fb66362..0000000
--- a/packages/SystemUI/res/drawable-mdpi/sysbar_signal_20.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/sysbar_signal_30.png b/packages/SystemUI/res/drawable-mdpi/sysbar_signal_30.png
deleted file mode 100644
index a87d94e..0000000
--- a/packages/SystemUI/res/drawable-mdpi/sysbar_signal_30.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/sysbar_signal_40.png b/packages/SystemUI/res/drawable-mdpi/sysbar_signal_40.png
deleted file mode 100644
index 8e229d5..0000000
--- a/packages/SystemUI/res/drawable-mdpi/sysbar_signal_40.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/sysbar_signal_50.png b/packages/SystemUI/res/drawable-mdpi/sysbar_signal_50.png
deleted file mode 100644
index fe989d4..0000000
--- a/packages/SystemUI/res/drawable-mdpi/sysbar_signal_50.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/sysbar_signal_60.png b/packages/SystemUI/res/drawable-mdpi/sysbar_signal_60.png
deleted file mode 100644
index aac57dc..0000000
--- a/packages/SystemUI/res/drawable-mdpi/sysbar_signal_60.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/sysbar_signal_70.png b/packages/SystemUI/res/drawable-mdpi/sysbar_signal_70.png
deleted file mode 100644
index 2281968..0000000
--- a/packages/SystemUI/res/drawable-mdpi/sysbar_signal_70.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/sysbar_signal_80.png b/packages/SystemUI/res/drawable-mdpi/sysbar_signal_80.png
deleted file mode 100644
index 7177ae1..0000000
--- a/packages/SystemUI/res/drawable-mdpi/sysbar_signal_80.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/sysbar_signal_90.png b/packages/SystemUI/res/drawable-mdpi/sysbar_signal_90.png
deleted file mode 100644
index 7f60480..0000000
--- a/packages/SystemUI/res/drawable-mdpi/sysbar_signal_90.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable/sysbar_battery.xml b/packages/SystemUI/res/drawable/sysbar_battery.xml
deleted file mode 100644
index 9551bf0..0000000
--- a/packages/SystemUI/res/drawable/sysbar_battery.xml
+++ /dev/null
@@ -1,33 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/* //device/apps/common/res/drawable/stat_sys_battery.xml
-**
-** Copyright 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.
-*/
--->
-
-<level-list xmlns:android="http://schemas.android.com/apk/res/android">
- <item android:maxLevel="01" android:drawable="@drawable/sysbar_battery_0" />
- <item android:maxLevel="10" android:drawable="@drawable/sysbar_battery_10" />
- <item android:maxLevel="20" android:drawable="@drawable/sysbar_battery_20" />
- <item android:maxLevel="30" android:drawable="@drawable/sysbar_battery_30" />
- <item android:maxLevel="40" android:drawable="@drawable/sysbar_battery_40" />
- <item android:maxLevel="50" android:drawable="@drawable/sysbar_battery_50" />
- <item android:maxLevel="60" android:drawable="@drawable/sysbar_battery_60" />
- <item android:maxLevel="70" android:drawable="@drawable/sysbar_battery_70" />
- <item android:maxLevel="80" android:drawable="@drawable/sysbar_battery_80" />
- <item android:maxLevel="90" android:drawable="@drawable/sysbar_battery_90" />
- <item android:maxLevel="101" android:drawable="@drawable/sysbar_battery_100" />
-</level-list>
diff --git a/packages/SystemUI/res/drawable/sysbar_batterymini.xml b/packages/SystemUI/res/drawable/sysbar_batterymini.xml
deleted file mode 100644
index c7300e6..0000000
--- a/packages/SystemUI/res/drawable/sysbar_batterymini.xml
+++ /dev/null
@@ -1,29 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/* //device/apps/common/res/drawable/stat_sys_battery.xml
-**
-** Copyright 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.
-*/
--->
-
-<clip xmlns:android="http://schemas.android.com/apk/res/android"
- android:clipOrientation="horizontal"
- android:maxLevel="100"
- android:gravity="left">
- <level-list>
- <item android:maxLevel="1500" android:drawable="@drawable/sysbar_batterymini_red" />
- <item android:maxLevel="10000" android:drawable="@drawable/sysbar_batterymini_100" />
- </level-list>
-</clip>
diff --git a/packages/SystemUI/res/drawable/sysbar_signal.xml b/packages/SystemUI/res/drawable/sysbar_signal.xml
deleted file mode 100644
index 9561c37..0000000
--- a/packages/SystemUI/res/drawable/sysbar_signal.xml
+++ /dev/null
@@ -1,33 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/* //device/apps/common/res/drawable/stat_sys_battery.xml
-**
-** Copyright 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.
-*/
--->
-
-<level-list xmlns:android="http://schemas.android.com/apk/res/android">
- <item android:maxLevel="01" android:drawable="@drawable/sysbar_signal_0" />
- <item android:maxLevel="10" android:drawable="@drawable/sysbar_signal_10" />
- <item android:maxLevel="20" android:drawable="@drawable/sysbar_signal_20" />
- <item android:maxLevel="30" android:drawable="@drawable/sysbar_signal_30" />
- <item android:maxLevel="40" android:drawable="@drawable/sysbar_signal_40" />
- <item android:maxLevel="50" android:drawable="@drawable/sysbar_signal_50" />
- <item android:maxLevel="60" android:drawable="@drawable/sysbar_signal_60" />
- <item android:maxLevel="70" android:drawable="@drawable/sysbar_signal_70" />
- <item android:maxLevel="80" android:drawable="@drawable/sysbar_signal_80" />
- <item android:maxLevel="90" android:drawable="@drawable/sysbar_signal_90" />
- <item android:maxLevel="101" android:drawable="@drawable/sysbar_signal_100" />
-</level-list>
diff --git a/packages/SystemUI/res/drawable/sysbar_signalmini.xml b/packages/SystemUI/res/drawable/sysbar_signalmini.xml
deleted file mode 100644
index 598bf10..0000000
--- a/packages/SystemUI/res/drawable/sysbar_signalmini.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/* //device/apps/common/res/drawable/stat_sys_battery.xml
-**
-** Copyright 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.
-*/
--->
-
-<clip xmlns:android="http://schemas.android.com/apk/res/android"
- android:clipOrientation="horizontal"
- android:gravity="right"
- android:maxLevel="10000"
- android:drawable="@drawable/sysbar_signalmini_100" />
diff --git a/packages/SystemUI/res/drawable/sysbar_wifi.xml b/packages/SystemUI/res/drawable/sysbar_wifi.xml
deleted file mode 100644
index 9561c37..0000000
--- a/packages/SystemUI/res/drawable/sysbar_wifi.xml
+++ /dev/null
@@ -1,33 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/* //device/apps/common/res/drawable/stat_sys_battery.xml
-**
-** Copyright 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.
-*/
--->
-
-<level-list xmlns:android="http://schemas.android.com/apk/res/android">
- <item android:maxLevel="01" android:drawable="@drawable/sysbar_signal_0" />
- <item android:maxLevel="10" android:drawable="@drawable/sysbar_signal_10" />
- <item android:maxLevel="20" android:drawable="@drawable/sysbar_signal_20" />
- <item android:maxLevel="30" android:drawable="@drawable/sysbar_signal_30" />
- <item android:maxLevel="40" android:drawable="@drawable/sysbar_signal_40" />
- <item android:maxLevel="50" android:drawable="@drawable/sysbar_signal_50" />
- <item android:maxLevel="60" android:drawable="@drawable/sysbar_signal_60" />
- <item android:maxLevel="70" android:drawable="@drawable/sysbar_signal_70" />
- <item android:maxLevel="80" android:drawable="@drawable/sysbar_signal_80" />
- <item android:maxLevel="90" android:drawable="@drawable/sysbar_signal_90" />
- <item android:maxLevel="101" android:drawable="@drawable/sysbar_signal_100" />
-</level-list>
diff --git a/packages/SystemUI/res/drawable/sysbar_wifimini.xml b/packages/SystemUI/res/drawable/sysbar_wifimini.xml
deleted file mode 100644
index ca6c9ed..0000000
--- a/packages/SystemUI/res/drawable/sysbar_wifimini.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/* //device/apps/common/res/drawable/stat_sys_battery.xml
-**
-** Copyright 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.
-*/
--->
-
-<clip xmlns:android="http://schemas.android.com/apk/res/android"
- android:clipOrientation="horizontal"
- android:gravity="right"
- android:maxLevel="100"
- android:drawable="@drawable/sysbar_signalmini_100" />
diff --git a/packages/SystemUI/res/layout-xlarge/status_bar.xml b/packages/SystemUI/res/layout-xlarge/status_bar.xml
index 590132f..a6e5c89 100644
--- a/packages/SystemUI/res/layout-xlarge/status_bar.xml
+++ b/packages/SystemUI/res/layout-xlarge/status_bar.xml
@@ -25,84 +25,9 @@
android:id="@+id/bar_contents"
android:layout_width="match_parent"
android:layout_height="match_parent"
+ android:animateLayoutChanges="true"
>
- <ImageView
- android:id="@+id/notificationTrigger"
- android:layout_width="wrap_content"
- android:layout_height="match_parent"
- android:layout_alignParentRight="true"
- android:layout_marginLeft="6dip"
- android:src="@drawable/ic_sysbar_noti_none"
- android:background="@drawable/ic_sysbar_icon_bg"
- android:gravity="center"
- />
-
- <LinearLayout
- android:id="@+id/notificationButtons"
- android:layout_width="wrap_content"
- android:layout_height="match_parent"
- android:layout_toLeftOf="@+id/notificationTrigger"
- android:gravity="center_vertical"
- android:orientation="horizontal"
- android:visibility="gone"
- >
-
- <TextView android:id="@+id/clear_all_button"
- style="?android:attr/textAppearance"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="right|center_vertical"
- android:layout_marginTop="2dip"
- android:layout_marginBottom="1dip"
- android:layout_marginRight="10dip"
- android:padding="6dip"
- android:textSize="14sp"
- android:text="@string/status_bar_clear_all_button"
- />
-
- <TextView android:id="@+id/do_not_disturb"
- style="?android:attr/textAppearance"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="right|center_vertical"
- android:layout_marginTop="2dip"
- android:layout_marginBottom="1dip"
- android:layout_marginRight="10dip"
- android:padding="6dip"
- android:textSize="14sp"
- android:text="@string/status_bar_do_not_disturb_button"
- />
-
- </LinearLayout>
-
- <com.android.systemui.statusbar.tablet.NotificationIconArea
- android:id="@+id/notificationIcons"
- android:layout_width="wrap_content"
- android:layout_height="match_parent"
- android:layout_toLeftOf="@+id/notificationTrigger"
- android:gravity="center_vertical"
- android:orientation="horizontal"
- >
- <com.android.systemui.statusbar.tablet.InputMethodButton
- android:id="@+id/imeButton"
- android:layout_width="wrap_content"
- android:layout_height="match_parent"
- android:layout_marginLeft="8dip"
- android:src="@drawable/ic_sysbar_ime_default"
- android:background="@drawable/ic_sysbar_icon_bg"
- android:visibility="invisible"
- />
- <view
- class="com.android.systemui.statusbar.tablet.NotificationIconArea$IconLayout"
- android:id="@+id/icons"
- android:layout_width="wrap_content"
- android:layout_height="@*android:dimen/status_bar_icon_size"
- android:layout_marginLeft="8dip"
- />
- </com.android.systemui.statusbar.tablet.NotificationIconArea>
-
-
<FrameLayout
android:id="@+id/ticker"
android:layout_width="wrap_content"
@@ -114,11 +39,60 @@
android:animateLayoutChanges="true"
/>
- <include layout="@layout/status_bar_center"
- android:layout_width="256dip"
+ <LinearLayout
+ android:id="@+id/notificationArea"
+ android:layout_width="wrap_content"
android:layout_height="match_parent"
- android:layout_centerInParent="true"
- />
+ android:layout_alignParentRight="true"
+ android:orientation="horizontal"
+ >
+ <com.android.systemui.statusbar.tablet.NotificationIconArea
+ android:id="@+id/notificationIcons"
+ android:layout_width="wrap_content"
+ android:layout_height="match_parent"
+ android:gravity="center_vertical"
+ android:orientation="horizontal"
+ >
+ <view
+ class="com.android.systemui.statusbar.tablet.NotificationIconArea$IconLayout"
+ android:id="@+id/icons"
+ android:layout_width="wrap_content"
+ android:layout_height="@*android:dimen/status_bar_icon_size"
+ android:layout_marginLeft="8dip"
+ />
+ </com.android.systemui.statusbar.tablet.NotificationIconArea>
+
+ <LinearLayout
+ android:id="@+id/notificationTrigger"
+ android:layout_width="wrap_content"
+ android:layout_height="match_parent"
+ >
+ <com.android.systemui.statusbar.policy.Clock
+ style="@*android:style/TextAppearance.StatusBar.Icon"
+ android:id="@+id/clock"
+ android:layout_width="64dip"
+ android:layout_height="48dip"
+ android:singleLine="true"
+ android:gravity="center"
+ android:textSize="16sp"
+ android:textStyle="bold"
+ android:padding="2dip"
+ />
+ <ImageView
+ android:id="@+id/battery"
+ android:layout_height="wrap_content"
+ android:layout_width="wrap_content"
+ android:layout_gravity="center_vertical"
+ />
+ <ImageView
+ android:id="@+id/network"
+ android:layout_height="wrap_content"
+ android:layout_width="wrap_content"
+ android:layout_gravity="center_vertical"
+ android:src="@drawable/ic_sysbar_wifi_mini"
+ />
+ </LinearLayout>
+ </LinearLayout>
<LinearLayout
android:id="@+id/navigationArea"
@@ -126,9 +100,10 @@
android:layout_height="match_parent"
android:layout_alignParentLeft="true"
android:orientation="horizontal"
+ android:animateLayoutChanges="true"
>
- <com.android.systemui.statusbar.KeyButtonView android:id="@+id/back"
+ <com.android.systemui.statusbar.policy.KeyButtonView android:id="@+id/back"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:paddingLeft="15dip"
@@ -137,7 +112,7 @@
android:background="@drawable/ic_sysbar_icon_bg"
systemui:keyCode="4"
/>
- <com.android.systemui.statusbar.KeyButtonView android:id="@+id/home"
+ <com.android.systemui.statusbar.policy.KeyButtonView android:id="@+id/home"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:paddingLeft="15dip"
@@ -154,7 +129,7 @@
android:paddingLeft="15dip"
android:paddingRight="15dip"
/>
- <com.android.systemui.statusbar.KeyButtonView android:id="@+id/menu"
+ <com.android.systemui.statusbar.policy.KeyButtonView android:id="@+id/menu"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:paddingLeft="15dip"
@@ -185,6 +160,15 @@
android:gravity="center"
/>
</com.android.systemui.statusbar.tablet.ShirtPocket>
+ <com.android.systemui.statusbar.tablet.InputMethodButton
+ android:id="@+id/imeButton"
+ android:layout_width="wrap_content"
+ android:layout_height="match_parent"
+ android:layout_marginLeft="8dip"
+ android:src="@drawable/ic_sysbar_ime_default"
+ android:background="@drawable/ic_sysbar_icon_bg"
+ android:visibility="invisible"
+ />
</LinearLayout>
</RelativeLayout>
diff --git a/packages/SystemUI/res/layout-xlarge/status_bar_center.xml b/packages/SystemUI/res/layout-xlarge/status_bar_center.xml
deleted file mode 100644
index d4f0e50..0000000
--- a/packages/SystemUI/res/layout-xlarge/status_bar_center.xml
+++ /dev/null
@@ -1,72 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- 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.
--->
-
-<!-- Center of status bar: System info display, system info panel trigger -->
-<RelativeLayout android:id="@+id/systemInfo"
- xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:systemui="http://schemas.android.com/apk/res/com.android.systemui"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:layout_centerInParent="true"
- android:clickable="true"
- >
- <com.android.systemui.statusbar.Clock
- style="@*android:style/TextAppearance.StatusBar.Icon"
- android:id="@+id/clock"
- android:layout_width="64dip"
- android:layout_height="48dip"
- android:layout_centerInParent="true"
- android:singleLine="true"
- android:gravity="center"
- android:textSize="16sp"
- android:textStyle="bold"
- android:padding="2dip"
- />
- <ImageView
- android:id="@+id/battery"
- android:layout_width="64dip"
- android:layout_height="16dip"
- android:layout_toLeftOf="@id/clock"
- android:layout_centerInParent="true"
- android:background="@drawable/sysbar_minimeter_bg"
- />
- <ImageView
- android:id="@+id/signal"
- android:layout_width="64dip"
- android:layout_height="16dip"
- android:layout_toRightOf="@id/clock"
- android:layout_centerInParent="true"
- android:background="@drawable/sysbar_minimeter_bg"
- />
- <ImageView
- android:id="@+id/battery_icon"
- android:layout_height="30dip"
- android:layout_width="30dip"
- android:layout_toLeftOf="@id/battery"
- android:layout_centerInParent="true"
- android:src="@drawable/ic_sysbar_battery_mini"
- />
- <ImageView
- android:id="@+id/signal_icon"
- android:layout_height="30dip"
- android:layout_width="30dip"
- android:layout_toRightOf="@id/signal"
- android:layout_centerInParent="true"
- android:src="@drawable/ic_sysbar_wifi_mini"
- />
-</RelativeLayout>
-
-
diff --git a/packages/SystemUI/res/layout-xlarge/sysbar_panel_notifications.xml b/packages/SystemUI/res/layout-xlarge/sysbar_panel_notifications.xml
index 8cbf3e3..6a8ae40 100644
--- a/packages/SystemUI/res/layout-xlarge/sysbar_panel_notifications.xml
+++ b/packages/SystemUI/res/layout-xlarge/sysbar_panel_notifications.xml
@@ -28,11 +28,76 @@
android:animateLayoutChanges="true"
>
+ <com.android.systemui.statusbar.policy.Clock
+ android:id="@+id/clock"
+ android:layout_height="wrap_content"
+ android:layout_width="match_parent"
+ android:layout_alignParentTop="true"
+ android:gravity="right"
+ />
+
+ <com.android.systemui.statusbar.policy.DateView
+ android:id="@+id/date"
+ android:layout_height="wrap_content"
+ android:layout_width="match_parent"
+ android:layout_below="@id/clock"
+ android:gravity="right"
+ />
+
+ <Button
+ android:id="@+id/settings_button"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_below="@id/date"
+ android:layout_alignParentRight="true"
+ android:text="@string/system_panel_settings_button"
+ />
+
+ <ImageView
+ android:id="@+id/battery"
+ android:layout_height="wrap_content"
+ android:layout_width="wrap_content"
+ android:layout_alignParentLeft="true"
+ android:layout_alignBaseline="@id/settings_button"
+ android:src="@drawable/ic_sysbar_battery_mini"
+ android:baseline="17dp"
+ />
+
+ <TextView
+ android:id="@+id/battery_text"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_toRightOf="@id/battery"
+ android:layout_alignBaseline="@id/settings_button"
+ android:singleLine="true"
+ android:text="@string/system_panel_settings_button"
+ />
+
+ <ImageView
+ android:id="@+id/network"
+ android:layout_height="wrap_content"
+ android:layout_width="wrap_content"
+ android:layout_toRightOf="@id/battery_text"
+ android:layout_alignBaseline="@id/settings_button"
+ android:src="@drawable/ic_sysbar_wifi_mini"
+ android:baseline="21dp"
+ />
+
+ <TextView
+ android:id="@+id/network_text"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_toRightOf="@id/network"
+ android:layout_alignBaseline="@id/settings_button"
+ android:singleLine="true"
+ android:text="@string/system_panel_settings_button"
+ />
+
<ScrollView
android:id="@+id/notificationScroller"
android:layout_height="wrap_content"
android:layout_width="match_parent"
- android:animateLayoutChanges="true"
+ android:layout_below="@id/settings_button"
>
<LinearLayout
android:id="@+id/content"
diff --git a/packages/SystemUI/res/layout-xlarge/sysbar_panel_system.xml b/packages/SystemUI/res/layout-xlarge/sysbar_panel_system.xml
index e6ec9f4..a1792fd 100644
--- a/packages/SystemUI/res/layout-xlarge/sysbar_panel_system.xml
+++ b/packages/SystemUI/res/layout-xlarge/sysbar_panel_system.xml
@@ -95,7 +95,6 @@
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:scaleType="centerCrop"
- android:src="@drawable/sysbar_battery"
/>
<TextView android:id="@+id/battery_info"
style="@style/TextAppearance.StatusBar.SystemPanel"
@@ -106,7 +105,7 @@
/>
</RelativeLayout>
- <com.android.systemui.statusbar.Clock
+ <com.android.systemui.statusbar.policy.Clock
style="@style/TextAppearance.StatusBar.SystemPanel"
android:id="@+id/clock"
android:layout_width="wrap_content"
@@ -130,7 +129,6 @@
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:scaleType="centerCrop"
- android:src="@drawable/sysbar_signal"
/>
<TextView android:id="@+id/signal_info"
@@ -200,7 +198,7 @@
>
<!-- TODO: alarm -->
<!-- TODO: sync -->
- <com.android.systemui.statusbar.DateView
+ <com.android.systemui.statusbar.policy.DateView
android:id="@+id/date"
style="@style/TextAppearance.StatusBar.SystemPanel"
android:layout_width="wrap_content"
diff --git a/packages/SystemUI/res/layout/status_bar.xml b/packages/SystemUI/res/layout/status_bar.xml
index 2f1b36e8..c8f5772 100644
--- a/packages/SystemUI/res/layout/status_bar.xml
+++ b/packages/SystemUI/res/layout/status_bar.xml
@@ -19,7 +19,7 @@
-->
<!-- android:background="@drawable/status_bar_closed_default_background" -->
-<com.android.systemui.statusbar.StatusBarView
+<com.android.systemui.statusbar.phone.PhoneStatusBarView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:systemui="http://schemas.android.com/apk/res/com.android.systemui"
android:background="@drawable/status_bar_background"
@@ -33,7 +33,7 @@
android:layout_height="match_parent"
android:orientation="horizontal">
- <com.android.systemui.statusbar.IconMerger android:id="@+id/notificationIcons"
+ <com.android.systemui.statusbar.phone.IconMerger android:id="@+id/notificationIcons"
android:layout_width="0dip"
android:layout_weight="1"
android:layout_height="match_parent"
@@ -50,7 +50,7 @@
android:gravity="center_vertical"
android:orientation="horizontal"/>
- <com.android.systemui.statusbar.Clock
+ <com.android.systemui.statusbar.policy.Clock
android:textAppearance="@*android:style/TextAppearance.StatusBar.Icon"
android:layout_width="wrap_content"
android:layout_height="match_parent"
@@ -82,7 +82,7 @@
android:layout_height="25dip"
/>
</ImageSwitcher>
- <com.android.systemui.statusbar.TickerView android:id="@+id/tickerText"
+ <com.android.systemui.statusbar.phone.TickerView android:id="@+id/tickerText"
android:layout_width="0dip"
android:layout_weight="1"
android:layout_height="wrap_content"
@@ -100,10 +100,10 @@
android:layout_height="wrap_content"
android:singleLine="true"
/>
- </com.android.systemui.statusbar.TickerView>
+ </com.android.systemui.statusbar.phone.TickerView>
</LinearLayout>
- <com.android.systemui.statusbar.DateView android:id="@+id/date"
+ <com.android.systemui.statusbar.policy.DateView android:id="@+id/date"
android:textAppearance="@*android:style/TextAppearance.StatusBar.Icon"
android:layout_width="wrap_content"
android:layout_height="match_parent"
@@ -113,4 +113,4 @@
android:paddingRight="6px"
android:background="@drawable/status_bar_background"
/>
-</com.android.systemui.statusbar.StatusBarView>
+</com.android.systemui.statusbar.phone.PhoneStatusBarView>
diff --git a/packages/SystemUI/res/layout/status_bar_expanded.xml b/packages/SystemUI/res/layout/status_bar_expanded.xml
index b5b1b50..3ad199e 100644
--- a/packages/SystemUI/res/layout/status_bar_expanded.xml
+++ b/packages/SystemUI/res/layout/status_bar_expanded.xml
@@ -18,7 +18,7 @@
*/
-->
-<com.android.systemui.statusbar.ExpandedView xmlns:android="http://schemas.android.com/apk/res/android"
+<com.android.systemui.statusbar.phone.ExpandedView xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:focusable="true"
android:descendantFocusability="afterDescendants"
@@ -33,7 +33,7 @@
android:paddingRight="3dp"
android:background="@drawable/shade_header_background"
>
- <com.android.systemui.statusbar.CarrierLabel
+ <com.android.systemui.statusbar.phone.CarrierLabel
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
@@ -72,7 +72,7 @@
android:layout_height="match_parent"
android:fadingEdge="none"
>
- <com.android.systemui.statusbar.NotificationLinearLayout
+ <LinearLayout
android:id="@+id/notificationLinearLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
@@ -115,7 +115,7 @@
android:layout_height="wrap_content"
android:orientation="vertical"
/>
- </com.android.systemui.statusbar.NotificationLinearLayout>
+ </LinearLayout>
</ScrollView>
<ImageView
@@ -126,4 +126,4 @@
/>
</FrameLayout>
-</com.android.systemui.statusbar.ExpandedView>
+</com.android.systemui.statusbar.phone.ExpandedView>
diff --git a/packages/SystemUI/res/layout/status_bar_tracking.xml b/packages/SystemUI/res/layout/status_bar_tracking.xml
index a2b40e6..a0ddab5 100644
--- a/packages/SystemUI/res/layout/status_bar_tracking.xml
+++ b/packages/SystemUI/res/layout/status_bar_tracking.xml
@@ -15,7 +15,7 @@
limitations under the License.
-->
-<com.android.systemui.statusbar.TrackingView
+<com.android.systemui.statusbar.phone.TrackingView
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:visibility="gone"
@@ -26,13 +26,13 @@
android:paddingRight="0px"
>
- <com.android.systemui.statusbar.TrackingPatternView
+ <com.android.systemui.statusbar.phone.TrackingPatternView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
/>
- <com.android.systemui.statusbar.CloseDragHandle android:id="@+id/close"
+ <com.android.systemui.statusbar.phone.CloseDragHandle android:id="@+id/close"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
@@ -45,6 +45,6 @@
android:src="@drawable/shade_handlebar"
/>
- </com.android.systemui.statusbar.CloseDragHandle>
+ </com.android.systemui.statusbar.phone.CloseDragHandle>
-</com.android.systemui.statusbar.TrackingView>
+</com.android.systemui.statusbar.phone.TrackingView>
diff --git a/packages/SystemUI/res/values-xlarge/config.xml b/packages/SystemUI/res/values-xlarge/config.xml
index 6df883c..e6af4f5 100644
--- a/packages/SystemUI/res/values-xlarge/config.xml
+++ b/packages/SystemUI/res/values-xlarge/config.xml
@@ -24,7 +24,7 @@
<!-- Component to be used as the status bar service. Must implement the IStatusBar
interface. This name is in the ComponentName flattened format (package/class) -->
- <string name="config_statusBarComponent">com.android.systemui.statusbar.tablet.TabletStatusBarService</string>
+ <string name="config_statusBarComponent">com.android.systemui.statusbar.tablet.TabletStatusBar</string>
</resources>
diff --git a/packages/SystemUI/res/values-xlarge/strings.xml b/packages/SystemUI/res/values-xlarge/strings.xml
index 3c59c92..e305681 100644
--- a/packages/SystemUI/res/values-xlarge/strings.xml
+++ b/packages/SystemUI/res/values-xlarge/strings.xml
@@ -23,13 +23,6 @@
<!-- System panel ("Quick Settings") -->
- <!-- Text to display underneath the graphical battery meter. Should
- include the word for "battery" and a place for the percentage charge
- available. [CHAR LIMIT=20] -->
- <string name="system_panel_battery_meter_format">
- Battery: <xliff:g id="number">%d</xliff:g><xliff:g id="percent">%%</xliff:g>
- </string>
-
<!-- Text to display underneath the graphical signal strength meter when
no connection is available. [CHAR LIMIT=20] -->
<string name="system_panel_signal_meter_disconnected">
@@ -38,10 +31,9 @@
<!-- Text to display underneath the graphical signal strength meter when
it is displaying information about a connected, named Wi-Fi network.
- Should include the word for "Wi-Fi" and a placeholder for the
- wireless network's SSID. [CHAR LIMIT=20] -->
+ [CHAR LIMIT=20] -->
<string name="system_panel_signal_meter_wifi_ssid_format">
- Wi-Fi: <xliff:g id="ssid">%s</xliff:g>
+ <xliff:g id="ssid">%s</xliff:g>
</string>
<!-- Text to display underneath the graphical signal strength meter when
diff --git a/packages/SystemUI/res/values/config.xml b/packages/SystemUI/res/values/config.xml
index 07cb52a..86beb14 100644
--- a/packages/SystemUI/res/values/config.xml
+++ b/packages/SystemUI/res/values/config.xml
@@ -33,7 +33,7 @@
<!-- Component to be used as the status bar service. Must implement the IStatusBar
interface. This name is in the ComponentName flattened format (package/class) -->
- <string name="config_statusBarComponent" translatable="false">com.android.systemui.statusbar.PhoneStatusBarService</string>
+ <string name="config_statusBarComponent" translatable="false">com.android.systemui.statusbar.phone.PhoneStatusBar</string>
</resources>
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index a65de37..e8c3c91 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -18,7 +18,7 @@
-->
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<!-- Name of the status bar as seen in the applications info settings page. [CHAR LIMIT=12] -->
- <string name="app_label">Status Bar</string>
+ <string name="app_label">System UI</string>
<!-- The text for the button in the notification window-shade that clears
all of the currently visible notifications. [CHAR LIMIT=10]-->
@@ -74,6 +74,10 @@
<!-- Name of the button that links to the Settings app. [CHAR LIMIT=NONE] -->
<string name="system_panel_settings_button">Settings</string>
+ <!-- Text to display next to the graphical battery meter. [CHAR LIMIT=3] -->
+ <string name="system_panel_battery_meter_format" translatable="false">
+ <xliff:g id="number">%d</xliff:g><xliff:g id="percent">%%</xliff:g>
+ </string>
<!-- Recent Tasks dialog: title [CHAR LIMIT=30] -->
<string name="recent_tasks_title">Recent</string>
diff --git a/packages/SystemUI/res/values/styles.xml b/packages/SystemUI/res/values/styles.xml
index 5aefb02..86ffb4d 100644
--- a/packages/SystemUI/res/values/styles.xml
+++ b/packages/SystemUI/res/values/styles.xml
@@ -39,4 +39,17 @@
<item name="android:textStyle">normal</item>
<item name="android:textColor">#FFFFFFFF</item>
</style>
+
+ <style name="Animation" />
+
+ <style name="Animation.ShirtPocketPanel">
+ <item name="android:windowEnterAnimation">@*android:anim/grow_fade_in_from_bottom</item>
+ <item name="android:windowExitAnimation">@*android:anim/shrink_fade_out_from_bottom</item>
+ </style>
+
+ <style name="Animation.RecentPanel">
+ <item name="android:windowEnterAnimation">@*android:anim/grow_fade_in_from_bottom</item>
+ <item name="android:windowExitAnimation">@*android:anim/shrink_fade_out_from_bottom</item>
+ </style>
+
</resources>
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLinearLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLinearLayout.java
deleted file mode 100644
index 8105352..0000000
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLinearLayout.java
+++ /dev/null
@@ -1,29 +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.systemui.statusbar;
-
-import android.content.Context;
-import android.util.AttributeSet;
-import android.widget.LinearLayout;
-
-
-public class NotificationLinearLayout extends LinearLayout {
- public NotificationLinearLayout(Context context, AttributeSet attrs) {
- super(context, attrs);
- }
-}
-
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarService.java b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBar.java
similarity index 95%
rename from packages/SystemUI/src/com/android/systemui/statusbar/StatusBarService.java
rename to packages/SystemUI/src/com/android/systemui/statusbar/StatusBar.java
index 776b59c..731f6cd 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarService.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBar.java
@@ -34,7 +34,6 @@
import java.util.ArrayList;
-import com.android.internal.statusbar.IStatusBar;
import com.android.internal.statusbar.IStatusBarService;
import com.android.internal.statusbar.StatusBarIcon;
import com.android.internal.statusbar.StatusBarIconList;
@@ -43,8 +42,8 @@
import com.android.systemui.SystemUI;
import com.android.systemui.R;
-public abstract class StatusBarService extends SystemUI implements CommandQueue.Callbacks {
- static final String TAG = "StatusBarService";
+public abstract class StatusBar extends SystemUI implements CommandQueue.Callbacks {
+ static final String TAG = "StatusBar";
private static final boolean SPEW = false;
protected CommandQueue mCommandQueue;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java
index 8419e56..9a61be6 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java
@@ -84,7 +84,7 @@
if (!iconEquals) {
Drawable drawable = getIcon(icon);
if (drawable == null) {
- Slog.w(StatusBarService.TAG, "No icon for slot " + mSlot);
+ Slog.w(StatusBar.TAG, "No icon for slot " + mSlot);
return false;
}
setImageDrawable(drawable);
@@ -130,7 +130,7 @@
try {
r = context.getPackageManager().getResourcesForApplication(icon.iconPackage);
} catch (PackageManager.NameNotFoundException ex) {
- Slog.e(StatusBarService.TAG, "Icon package not found: " + icon.iconPackage);
+ Slog.e(StatusBar.TAG, "Icon package not found: " + icon.iconPackage);
return null;
}
} else {
@@ -144,7 +144,7 @@
try {
return r.getDrawable(icon.iconId);
} catch (RuntimeException e) {
- Slog.w(StatusBarService.TAG, "Icon not found in "
+ Slog.w(StatusBar.TAG, "Icon not found in "
+ (icon.iconPackage != null ? icon.iconId : "<system>")
+ ": " + Integer.toHexString(icon.iconId));
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/CarrierLabel.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CarrierLabel.java
similarity index 98%
rename from packages/SystemUI/src/com/android/systemui/statusbar/CarrierLabel.java
rename to packages/SystemUI/src/com/android/systemui/statusbar/phone/CarrierLabel.java
index 31b78b6..d8441f2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/CarrierLabel.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CarrierLabel.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.systemui.statusbar;
+package com.android.systemui.statusbar.phone;
import android.content.BroadcastReceiver;
import android.content.Context;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/CloseDragHandle.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CloseDragHandle.java
similarity index 95%
rename from packages/SystemUI/src/com/android/systemui/statusbar/CloseDragHandle.java
rename to packages/SystemUI/src/com/android/systemui/statusbar/phone/CloseDragHandle.java
index 0f6723e..ba64282 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/CloseDragHandle.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CloseDragHandle.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.systemui.statusbar;
+package com.android.systemui.statusbar.phone;
import android.content.Context;
import android.util.AttributeSet;
@@ -23,7 +23,7 @@
public class CloseDragHandle extends LinearLayout {
- PhoneStatusBarService mService;
+ PhoneStatusBar mService;
public CloseDragHandle(Context context, AttributeSet attrs) {
super(context, attrs);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandedView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ExpandedView.java
similarity index 86%
rename from packages/SystemUI/src/com/android/systemui/statusbar/ExpandedView.java
rename to packages/SystemUI/src/com/android/systemui/statusbar/phone/ExpandedView.java
index a2d4b95..92b8976 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandedView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ExpandedView.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.systemui.statusbar;
+package com.android.systemui.statusbar.phone;
import android.content.Context;
import android.util.AttributeSet;
@@ -27,7 +27,7 @@
public class ExpandedView extends LinearLayout {
- PhoneStatusBarService mService;
+ PhoneStatusBar mService;
int mPrevHeight = -1;
public ExpandedView(Context context, AttributeSet attrs) {
@@ -50,10 +50,10 @@
super.onLayout(changed, left, top, right, bottom);
int height = bottom - top;
if (height != mPrevHeight) {
- //Slog.d(StatusBarService.TAG, "height changed old=" + mPrevHeight
+ //Slog.d(StatusBar.TAG, "height changed old=" + mPrevHeight
// + " new=" + height);
mPrevHeight = height;
- mService.updateExpandedViewPos(PhoneStatusBarService.EXPANDED_LEAVE_ALONE);
+ mService.updateExpandedViewPos(PhoneStatusBar.EXPANDED_LEAVE_ALONE);
}
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/IconMerger.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/IconMerger.java
similarity index 97%
rename from packages/SystemUI/src/com/android/systemui/statusbar/IconMerger.java
rename to packages/SystemUI/src/com/android/systemui/statusbar/phone/IconMerger.java
index e87d003..e1d17a8 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/IconMerger.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/IconMerger.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.systemui.statusbar;
+package com.android.systemui.statusbar.phone;
import android.content.Context;
import android.os.Handler;
@@ -26,7 +26,7 @@
import com.android.internal.statusbar.StatusBarIcon;
import com.android.systemui.R;
-
+import com.android.systemui.statusbar.StatusBarIconView;
public class IconMerger extends LinearLayout {
private static final String TAG = "IconMerger";
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/PhoneStatusBarService.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
similarity index 98%
rename from packages/SystemUI/src/com/android/systemui/statusbar/PhoneStatusBarService.java
rename to packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
index d3d2285..2dad81c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/PhoneStatusBarService.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.systemui.statusbar;
+package com.android.systemui.statusbar.phone;
import android.app.Service;
import android.app.ActivityManagerNative;
@@ -66,19 +66,19 @@
import java.util.HashMap;
import java.util.Set;
-import com.android.internal.statusbar.IStatusBar;
-import com.android.internal.statusbar.IStatusBarService;
import com.android.internal.statusbar.StatusBarIcon;
import com.android.internal.statusbar.StatusBarIconList;
import com.android.internal.statusbar.StatusBarNotification;
import com.android.systemui.R;
-import com.android.systemui.statusbar.policy.StatusBarPolicy;
+import com.android.systemui.statusbar.NotificationData;
+import com.android.systemui.statusbar.StatusBar;
+import com.android.systemui.statusbar.StatusBarIconView;
+import com.android.systemui.statusbar.policy.DateView;
-
-public class PhoneStatusBarService extends StatusBarService {
- static final String TAG = "PhoneStatusBarService";
+public class PhoneStatusBar extends StatusBar {
+ static final String TAG = "PhoneStatusBar";
static final boolean SPEW = false;
public static final String ACTION_STATUSBAR_START
@@ -95,12 +95,12 @@
// will likely move to a resource or other tunable param at some point
private static final int INTRUDER_ALERT_DECAY_MS = 10000;
- StatusBarPolicy mIconPolicy;
+ PhoneStatusBarPolicy mIconPolicy;
int mIconSize;
Display mDisplay;
- StatusBarView mStatusBarView;
+ PhoneStatusBarView mStatusBarView;
int mPixelFormat;
H mHandler = new H();
Object mQueueLock = new Object();
@@ -202,7 +202,7 @@
addIntruderView();
// Lastly, call to the icon policy to install/update all the icons.
- mIconPolicy = new StatusBarPolicy(mContext);
+ mIconPolicy = new PhoneStatusBarPolicy(mContext);
}
// ================================================================================
@@ -223,7 +223,8 @@
mIntruderAlertView.setVisibility(View.GONE);
mIntruderAlertView.setClickable(true);
- StatusBarView sb = (StatusBarView)View.inflate(context, R.layout.status_bar, null);
+ PhoneStatusBarView sb = (PhoneStatusBarView)View.inflate(context,
+ R.layout.status_bar, null);
sb.mService = this;
// figure out which pixel-format to use for the status bar.
@@ -1304,7 +1305,6 @@
}
void setDateViewVisibility(boolean visible, int anim) {
- mDateView.setUpdates(visible);
mDateView.setVisibility(visible ? View.VISIBLE : View.INVISIBLE);
mDateView.startAnimation(loadAnim(anim, null));
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarPolicy.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java
similarity index 99%
rename from packages/SystemUI/src/com/android/systemui/statusbar/StatusBarPolicy.java
rename to packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java
index 4f5c3ae..73b6723 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarPolicy.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.systemui.statusbar.policy;
+package com.android.systemui.statusbar.phone;
import android.app.StatusBarManager;
import android.bluetooth.BluetoothAdapter;
@@ -71,8 +71,8 @@
* bar at boot time. It goes through the normal API for icons, even though it probably
* strictly doesn't need to.
*/
-public class StatusBarPolicy {
- private static final String TAG = "StatusBarPolicy";
+public class PhoneStatusBarPolicy {
+ private static final String TAG = "PhoneStatusBarPolicy";
// message codes for the handler
private static final int EVENT_BATTERY_CLOSE = 4;
@@ -368,7 +368,7 @@
}
};
- public StatusBarPolicy(Context context) {
+ public PhoneStatusBarPolicy(Context context) {
mContext = context;
mService = (StatusBarManager)context.getSystemService(Context.STATUS_BAR_SERVICE);
mSignalStrength = new SignalStrength();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java
similarity index 93%
rename from packages/SystemUI/src/com/android/systemui/statusbar/StatusBarView.java
rename to packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java
index 20fc41f..84c524a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.systemui.statusbar;
+package com.android.systemui.statusbar.phone;
import android.content.Context;
import android.content.res.Configuration;
@@ -29,13 +29,14 @@
import android.widget.FrameLayout;
import com.android.systemui.R;
+import com.android.systemui.statusbar.policy.FixedSizeDrawable;
-public class StatusBarView extends FrameLayout {
- private static final String TAG = "StatusBarView";
+public class PhoneStatusBarView extends FrameLayout {
+ private static final String TAG = "PhoneStatusBarView";
static final int DIM_ANIM_TIME = 400;
- PhoneStatusBarService mService;
+ PhoneStatusBar mService;
boolean mTracking;
int mStartX, mStartY;
ViewGroup mNotificationIcons;
@@ -50,7 +51,7 @@
Rect mButtonBounds = new Rect();
boolean mCapturingEvents = true;
- public StatusBarView(Context context, AttributeSet attrs) {
+ public PhoneStatusBarView(Context context, AttributeSet attrs) {
super(context, attrs);
}
@@ -98,7 +99,7 @@
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
- mService.updateExpandedViewPos(PhoneStatusBarService.EXPANDED_LEAVE_ALONE);
+ mService.updateExpandedViewPos(PhoneStatusBar.EXPANDED_LEAVE_ALONE);
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/Ticker.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/Ticker.java
similarity index 98%
rename from packages/SystemUI/src/com/android/systemui/statusbar/Ticker.java
rename to packages/SystemUI/src/com/android/systemui/statusbar/phone/Ticker.java
index e7b0509..8ee12de 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/Ticker.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/Ticker.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.systemui.statusbar;
+package com.android.systemui.statusbar.phone;
import android.content.Context;
import android.graphics.drawable.Drawable;
@@ -36,7 +36,9 @@
import com.android.internal.statusbar.StatusBarIcon;
import com.android.internal.statusbar.StatusBarNotification;
import com.android.internal.util.CharSequences;
+
import com.android.systemui.R;
+import com.android.systemui.statusbar.StatusBarIconView;
public abstract class Ticker {
private static final int TICKER_SEGMENT_DELAY = 3000;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/TickerView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/TickerView.java
similarity index 95%
rename from packages/SystemUI/src/com/android/systemui/statusbar/TickerView.java
rename to packages/SystemUI/src/com/android/systemui/statusbar/phone/TickerView.java
index 8140811..8aa3837 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/TickerView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/TickerView.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.systemui.statusbar;
+package com.android.systemui.statusbar.phone;
import android.content.Context;
import android.util.AttributeSet;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/TrackingPatternView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/TrackingPatternView.java
similarity index 97%
rename from packages/SystemUI/src/com/android/systemui/statusbar/TrackingPatternView.java
rename to packages/SystemUI/src/com/android/systemui/statusbar/phone/TrackingPatternView.java
index ba6f15d..d2ed5ff 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/TrackingPatternView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/TrackingPatternView.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.systemui.statusbar;
+package com.android.systemui.statusbar.phone;
import android.content.Context;
import android.content.res.TypedArray;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/TrackingView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/TrackingView.java
similarity index 95%
rename from packages/SystemUI/src/com/android/systemui/statusbar/TrackingView.java
rename to packages/SystemUI/src/com/android/systemui/statusbar/phone/TrackingView.java
index c59eb6a..fd32a3d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/TrackingView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/TrackingView.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.systemui.statusbar;
+package com.android.systemui.statusbar.phone;
import android.content.Context;
import android.util.AttributeSet;
@@ -26,7 +26,7 @@
public class TrackingView extends LinearLayout {
final Display mDisplay;
- PhoneStatusBarService mService;
+ PhoneStatusBar mService;
boolean mTracking;
int mStartX, mStartY;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryController.java
new file mode 100644
index 0000000..a1efdd4
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryController.java
@@ -0,0 +1,74 @@
+/*
+ * 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 com.android.systemui.statusbar.policy;
+
+import java.util.ArrayList;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.os.BatteryManager;
+import android.util.Slog;
+import android.widget.ImageView;
+import android.widget.TextView;
+
+import com.android.systemui.R;
+
+public class BatteryController extends BroadcastReceiver {
+ private static final String TAG = "StatusBar.BatteryController";
+
+ private Context mContext;
+ private ArrayList<ImageView> mIconViews = new ArrayList<ImageView>();
+ private ArrayList<TextView> mLabelViews = new ArrayList<TextView>();
+
+ public BatteryController(Context context) {
+ mContext = context;
+
+ IntentFilter filter = new IntentFilter();
+ filter.addAction(Intent.ACTION_BATTERY_CHANGED);
+ context.registerReceiver(this, filter);
+ }
+
+ public void addIconView(ImageView v) {
+ mIconViews.add(v);
+ }
+
+ public void addLabelView(TextView v) {
+ mLabelViews.add(v);
+ }
+
+ public void onReceive(Context context, Intent intent) {
+ final String action = intent.getAction();
+ if (action.equals(Intent.ACTION_BATTERY_CHANGED)) {
+ final int level = intent.getIntExtra(BatteryManager.EXTRA_LEVEL, 0);
+ int N = mIconViews.size();
+ for (int i=0; i<N; i++) {
+ final int icon = intent.getIntExtra(BatteryManager.EXTRA_ICON_SMALL, 0);
+ ImageView v = mIconViews.get(i);
+ v.setImageResource(icon);
+ v.setImageLevel(level);
+ }
+ N = mLabelViews.size();
+ for (int i=0; i<N; i++) {
+ //final boolean plugged = intent.getIntExtra(BatteryManager.EXTRA_PLUGGED, 0) != 0;
+ TextView v = mLabelViews.get(i);
+ v.setText(mContext.getString(R.string.system_panel_battery_meter_format, level));
+ }
+ }
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/Clock.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/Clock.java
similarity index 99%
rename from packages/SystemUI/src/com/android/systemui/statusbar/Clock.java
rename to packages/SystemUI/src/com/android/systemui/statusbar/policy/Clock.java
index 9fc8df5..69872df 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/Clock.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/Clock.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.systemui.statusbar;
+package com.android.systemui.statusbar.policy;
import android.content.BroadcastReceiver;
import android.content.Context;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/DateView.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/DateView.java
similarity index 67%
rename from packages/SystemUI/src/com/android/systemui/statusbar/DateView.java
rename to packages/SystemUI/src/com/android/systemui/statusbar/policy/DateView.java
index e127038..136f4a94 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/DateView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/DateView.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.systemui.statusbar;
+package com.android.systemui.statusbar.policy;
import android.content.BroadcastReceiver;
import android.content.Context;
@@ -24,6 +24,8 @@
import android.util.Slog;
import android.widget.TextView;
import android.view.MotionEvent;
+import android.view.View;
+import android.view.ViewParent;
import java.text.DateFormat;
import java.util.Date;
@@ -31,7 +33,9 @@
public final class DateView extends TextView {
private static final String TAG = "DateView";
- private boolean mUpdating = false;
+ private boolean mAttachedToWindow;
+ private boolean mWindowVisible;
+ private boolean mUpdating;
private BroadcastReceiver mIntentReceiver = new BroadcastReceiver() {
@Override
@@ -51,12 +55,28 @@
@Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
+ mAttachedToWindow = true;
+ setUpdates();
}
@Override
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
- setUpdates(false);
+ mAttachedToWindow = false;
+ setUpdates();
+ }
+
+ @Override
+ protected void onWindowVisibilityChanged(int visibility) {
+ super.onWindowVisibilityChanged(visibility);
+ mWindowVisible = visibility == VISIBLE;
+ setUpdates();
+ }
+
+ @Override
+ protected void onVisibilityChanged(View changedView, int visibility) {
+ super.onVisibilityChanged(changedView, visibility);
+ setUpdates();
}
@Override
@@ -67,10 +87,26 @@
private final void updateClock() {
Date now = new Date();
- setText(DateFormat.getDateInstance(DateFormat.LONG).format(now));
+ setText(DateFormat.getDateInstance(DateFormat.FULL).format(now));
}
- public void setUpdates(boolean update) {
+ private boolean isVisible() {
+ View v = this;
+ while (true) {
+ if (v.getVisibility() != VISIBLE) {
+ return false;
+ }
+ final ViewParent parent = v.getParent();
+ if (parent instanceof View) {
+ v = (View)parent;
+ } else {
+ return true;
+ }
+ }
+ }
+
+ private void setUpdates() {
+ boolean update = mAttachedToWindow && mWindowVisible && isVisible();
if (update != mUpdating) {
mUpdating = update;
if (update) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/FixedSizeDrawable.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/FixedSizeDrawable.java
similarity index 91%
rename from packages/SystemUI/src/com/android/systemui/statusbar/FixedSizeDrawable.java
rename to packages/SystemUI/src/com/android/systemui/statusbar/policy/FixedSizeDrawable.java
index eb22b61..8f2f5f9 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/FixedSizeDrawable.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/FixedSizeDrawable.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.systemui.statusbar;
+package com.android.systemui.statusbar.policy;
import android.graphics.drawable.Drawable;
import android.graphics.Canvas;
@@ -22,14 +22,14 @@
import android.graphics.Rect;
import android.util.Slog;
-class FixedSizeDrawable extends Drawable {
+public class FixedSizeDrawable extends Drawable {
Drawable mDrawable;
int mLeft;
int mTop;
int mRight;
int mBottom;
- FixedSizeDrawable(Drawable that) {
+ public FixedSizeDrawable(Drawable that) {
mDrawable = that;
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/KeyButtonView.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java
similarity index 85%
rename from packages/SystemUI/src/com/android/systemui/statusbar/KeyButtonView.java
rename to packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java
index b01c5e7..aed3dc7 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/KeyButtonView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.systemui.statusbar;
+package com.android.systemui.statusbar.policy;
import android.content.Context;
import android.content.res.TypedArray;
@@ -37,6 +37,8 @@
import com.android.systemui.R;
public class KeyButtonView extends ImageView {
+ private static final String TAG = "StatusBar.KeyButtonView";
+
IWindowManager mWindowManager;
long mDownTime;
boolean mSending, mLongPressed;
@@ -68,8 +70,7 @@
mCode = a.getInteger(R.styleable.KeyButtonView_keyCode, 0);
if (mCode == 0) {
- Slog.w(StatusBarService.TAG, "KeyButtonView without key code id=0x"
- + Integer.toHexString(getId()));
+ Slog.w(TAG, "KeyButtonView without key code id=0x" + Integer.toHexString(getId()));
}
a.recycle();
@@ -99,18 +100,20 @@
if (mSending) {
x = (int)ev.getX();
y = (int)ev.getY();
- if (x < 0 || x >= getWidth() || y < 0 || y >= getHeight()) {
- mSending = false;
- sendEvent(KeyEvent.ACTION_UP,
- KeyEvent.FLAG_FROM_SYSTEM | KeyEvent.FLAG_VIRTUAL_HARD_KEY
- | KeyEvent.FLAG_CANCELED);
- setPressed(false);
- removeCallbacks(mCheckLongPress);
- }
+ setPressed(x >= 0 && x < getWidth() && y >= 0 && y < getHeight());
+ }
+ break;
+ case MotionEvent.ACTION_CANCEL:
+ setPressed(false);
+ if (mSending && !mLongPressed) {
+ mSending = false;
+ sendEvent(KeyEvent.ACTION_UP,
+ KeyEvent.FLAG_FROM_SYSTEM | KeyEvent.FLAG_VIRTUAL_HARD_KEY
+ | KeyEvent.FLAG_CANCELED);
+ removeCallbacks(mCheckLongPress);
}
break;
case MotionEvent.ACTION_UP:
- case MotionEvent.ACTION_CANCEL:
setPressed(false);
if (mSending && !mLongPressed) {
mSending = false;
@@ -132,7 +135,7 @@
final KeyEvent ev = new KeyEvent(mDownTime, when, action, mCode, mRepeat,
0, 0, 0, flags, InputDevice.SOURCE_KEYBOARD);
try {
- //Slog.d(StatusBarService.TAG, "injecting event " + ev);
+ //Slog.d(TAG, "injecting event " + ev);
mWindowManager.injectInputEventNoWait(ev);
} catch (RemoteException ex) {
// System process is dead
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java
new file mode 100644
index 0000000..f1b76f6
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java
@@ -0,0 +1,623 @@
+/*
+ * 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 com.android.systemui.statusbar.policy;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.net.ConnectivityManager;
+import android.net.NetworkInfo;
+import android.net.wifi.SupplicantState;
+import android.net.wifi.WifiConfiguration;
+import android.net.wifi.WifiInfo;
+import android.net.wifi.WifiManager;
+import android.os.Binder;
+import android.os.RemoteException;
+import android.provider.Settings;
+import android.telephony.PhoneStateListener;
+import android.telephony.ServiceState;
+import android.telephony.SignalStrength;
+import android.telephony.TelephonyManager;
+import android.util.Slog;
+import android.widget.ImageView;
+import android.widget.TextView;
+
+import com.android.internal.app.IBatteryStats;
+import com.android.internal.telephony.IccCard;
+import com.android.internal.telephony.TelephonyIntents;
+import com.android.internal.telephony.cdma.EriInfo;
+import com.android.server.am.BatteryStatsService;
+
+import com.android.systemui.R;
+
+public class NetworkController extends BroadcastReceiver {
+ // debug
+ static final String TAG = "StatusBar.NetworkController";
+ static final boolean DEBUG = false;
+
+ // telephony
+ boolean mHspaDataDistinguishable;
+ final TelephonyManager mPhone;
+ boolean mDataConnected;
+ int mPhoneSignalIconId;
+ int mDataIconId;
+ IccCard.State mSimState = IccCard.State.READY;
+ int mPhoneState = TelephonyManager.CALL_STATE_IDLE;
+ int mDataState = TelephonyManager.DATA_DISCONNECTED;
+ int mDataActivity = TelephonyManager.DATA_ACTIVITY_NONE;
+ ServiceState mServiceState;
+ SignalStrength mSignalStrength;
+ int[] mDataIconList = TelephonyIcons.DATA_G[0];
+
+ // wifi
+ final WifiManager mWifiManager;
+ boolean mWifiEnabled, mWifiConnected;
+ int mWifiLevel;
+ String mWifiSsid;
+ int mWifiIconId;
+
+ // data connectivity (regardless of state, can we access the internet?)
+ // state of inet connection - 0 not connected, 100 connected
+ private int mInetCondition = 0;
+ private static final int INET_CONDITION_THRESHOLD = 50;
+
+ // our ui
+ Context mContext;
+ ArrayList<ImageView> mPhoneIconViews = new ArrayList<ImageView>();
+ ArrayList<ImageView> mDataIconViews = new ArrayList<ImageView>();
+ ArrayList<TextView> mLabelViews = new ArrayList<TextView>();
+ int mLastPhoneSignalIconId = -1;
+ int mLastCombinedDataIconId = -1;
+ String mLastLabel = "";
+
+ // yuck -- stop doing this here and put it in the framework
+ IBatteryStats mBatteryStats;
+
+ /**
+ * Construct this controller object and register for updates.
+ */
+ public NetworkController(Context context) {
+ mContext = context;
+
+ // telephony
+ mPhone = (TelephonyManager)context.getSystemService(Context.TELEPHONY_SERVICE);
+ mPhone.listen(mPhoneStateListener,
+ PhoneStateListener.LISTEN_SERVICE_STATE
+ | PhoneStateListener.LISTEN_SIGNAL_STRENGTHS
+ | PhoneStateListener.LISTEN_CALL_STATE
+ | PhoneStateListener.LISTEN_DATA_CONNECTION_STATE
+ | PhoneStateListener.LISTEN_DATA_ACTIVITY);
+ mHspaDataDistinguishable = mContext.getResources().getBoolean(
+ R.bool.config_hspa_data_distinguishable);
+
+
+ // wifi
+ mWifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
+
+ // broadcasts
+ IntentFilter filter = new IntentFilter();
+ filter.addAction(WifiManager.RSSI_CHANGED_ACTION);
+ filter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION);
+ filter.addAction(WifiManager.SUPPLICANT_STATE_CHANGED_ACTION);
+ filter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION);
+ filter.addAction(TelephonyIntents.ACTION_SIM_STATE_CHANGED);
+ context.registerReceiver(this, filter);
+
+ // yuck
+ mBatteryStats = BatteryStatsService.getService();
+ }
+
+ public void addPhoneIconView(ImageView v) {
+ mPhoneIconViews.add(v);
+ }
+
+ public void addCombinedDataIconView(ImageView v) {
+ mDataIconViews.add(v);
+ }
+
+ public void addLabelView(TextView v) {
+ mLabelViews.add(v);
+ }
+
+ public void onReceive(Context context, Intent intent) {
+ final String action = intent.getAction();
+ if (action.equals(WifiManager.RSSI_CHANGED_ACTION)
+ || action.equals(WifiManager.WIFI_STATE_CHANGED_ACTION)
+ || action.equals(WifiManager.SUPPLICANT_STATE_CHANGED_ACTION)
+ || action.equals(WifiManager.NETWORK_STATE_CHANGED_ACTION)) {
+ updateWifiState(intent);
+ refreshViews();
+ } else if (action.equals(TelephonyIntents.ACTION_SIM_STATE_CHANGED)) {
+ updateSimState(intent);
+ updateDataIcon();
+ refreshViews();
+ } else if (action.equals(ConnectivityManager.CONNECTIVITY_ACTION) ||
+ action.equals(ConnectivityManager.INET_CONDITION_ACTION)) {
+ updateConnectivity(intent);
+ refreshViews();
+ }
+ }
+
+
+ // ===== Telephony ==============================================================
+
+ PhoneStateListener mPhoneStateListener = new PhoneStateListener() {
+ @Override
+ public void onSignalStrengthsChanged(SignalStrength signalStrength) {
+ if (DEBUG) {
+ Slog.d(TAG, "onSignalStrengthsChanged signalStrength=" + signalStrength);
+ }
+ mSignalStrength = signalStrength;
+ updateTelephonySignalStrength();
+ refreshViews();
+ }
+
+ @Override
+ public void onServiceStateChanged(ServiceState state) {
+ if (DEBUG) {
+ Slog.d(TAG, "onServiceStateChanged state=" + state.getState());
+ }
+ mServiceState = state;
+ updateTelephonySignalStrength();
+ updateDataIcon();
+ refreshViews();
+ }
+
+ @Override
+ public void onCallStateChanged(int state, String incomingNumber) {
+ if (DEBUG) {
+ Slog.d(TAG, "onCallStateChanged state=" + state);
+ }
+ // In cdma, if a voice call is made, RSSI should switch to 1x.
+ if (isCdma()) {
+ updateTelephonySignalStrength();
+ refreshViews();
+ }
+ }
+
+ @Override
+ public void onDataConnectionStateChanged(int state, int networkType) {
+ if (DEBUG) {
+ Slog.d(TAG, "onDataConnectionStateChanged: state=" + state
+ + " type=" + networkType);
+ }
+ mDataState = state;
+ updateDataNetType(networkType);
+ updateDataIcon();
+ refreshViews();
+ }
+
+ @Override
+ public void onDataActivity(int direction) {
+ if (DEBUG) {
+ Slog.d(TAG, "onDataActivity: direction=" + direction);
+ }
+ mDataActivity = direction;
+ updateDataIcon();
+ refreshViews();
+ }
+ };
+
+ private final void updateSimState(Intent intent) {
+ String stateExtra = intent.getStringExtra(IccCard.INTENT_KEY_ICC_STATE);
+ if (IccCard.INTENT_VALUE_ICC_ABSENT.equals(stateExtra)) {
+ mSimState = IccCard.State.ABSENT;
+ }
+ else if (IccCard.INTENT_VALUE_ICC_READY.equals(stateExtra)) {
+ mSimState = IccCard.State.READY;
+ }
+ else if (IccCard.INTENT_VALUE_ICC_LOCKED.equals(stateExtra)) {
+ final String lockedReason = intent.getStringExtra(IccCard.INTENT_KEY_LOCKED_REASON);
+ if (IccCard.INTENT_VALUE_LOCKED_ON_PIN.equals(lockedReason)) {
+ mSimState = IccCard.State.PIN_REQUIRED;
+ }
+ else if (IccCard.INTENT_VALUE_LOCKED_ON_PUK.equals(lockedReason)) {
+ mSimState = IccCard.State.PUK_REQUIRED;
+ }
+ else {
+ mSimState = IccCard.State.NETWORK_LOCKED;
+ }
+ } else {
+ mSimState = IccCard.State.UNKNOWN;
+ }
+ }
+
+ private boolean isCdma() {
+ return (mSignalStrength != null) && !mSignalStrength.isGsm();
+ }
+
+ private boolean isEvdo() {
+ return ((mServiceState != null)
+ && ((mServiceState.getRadioTechnology() == ServiceState.RADIO_TECHNOLOGY_EVDO_0)
+ || (mServiceState.getRadioTechnology() == ServiceState.RADIO_TECHNOLOGY_EVDO_A)
+ || (mServiceState.getRadioTechnology() == ServiceState.RADIO_TECHNOLOGY_EVDO_B)));
+ }
+
+ private boolean hasService() {
+ if (mServiceState != null) {
+ switch (mServiceState.getState()) {
+ case ServiceState.STATE_OUT_OF_SERVICE:
+ case ServiceState.STATE_POWER_OFF:
+ return false;
+ default:
+ return true;
+ }
+ } else {
+ return false;
+ }
+ }
+
+ private int getCdmaLevel() {
+ if (mSignalStrength == null) return 0;
+ final int cdmaDbm = mSignalStrength.getCdmaDbm();
+ final int cdmaEcio = mSignalStrength.getCdmaEcio();
+ int levelDbm = 0;
+ int levelEcio = 0;
+
+ if (cdmaDbm >= -75) levelDbm = 4;
+ else if (cdmaDbm >= -85) levelDbm = 3;
+ else if (cdmaDbm >= -95) levelDbm = 2;
+ else if (cdmaDbm >= -100) levelDbm = 1;
+ else levelDbm = 0;
+
+ // Ec/Io are in dB*10
+ if (cdmaEcio >= -90) levelEcio = 4;
+ else if (cdmaEcio >= -110) levelEcio = 3;
+ else if (cdmaEcio >= -130) levelEcio = 2;
+ else if (cdmaEcio >= -150) levelEcio = 1;
+ else levelEcio = 0;
+
+ return (levelDbm < levelEcio) ? levelDbm : levelEcio;
+ }
+
+ private int getEvdoLevel() {
+ if (mSignalStrength == null) return 0;
+ int evdoDbm = mSignalStrength.getEvdoDbm();
+ int evdoSnr = mSignalStrength.getEvdoSnr();
+ int levelEvdoDbm = 0;
+ int levelEvdoSnr = 0;
+
+ if (evdoDbm >= -65) levelEvdoDbm = 4;
+ else if (evdoDbm >= -75) levelEvdoDbm = 3;
+ else if (evdoDbm >= -90) levelEvdoDbm = 2;
+ else if (evdoDbm >= -105) levelEvdoDbm = 1;
+ else levelEvdoDbm = 0;
+
+ if (evdoSnr >= 7) levelEvdoSnr = 4;
+ else if (evdoSnr >= 5) levelEvdoSnr = 3;
+ else if (evdoSnr >= 3) levelEvdoSnr = 2;
+ else if (evdoSnr >= 1) levelEvdoSnr = 1;
+ else levelEvdoSnr = 0;
+
+ return (levelEvdoDbm < levelEvdoSnr) ? levelEvdoDbm : levelEvdoSnr;
+ }
+
+ private final void updateTelephonySignalStrength() {
+ // Display signal strength while in "emergency calls only" mode
+ if (mServiceState == null || (!hasService() && !mServiceState.isEmergencyOnly())) {
+ //Slog.d(TAG, "updateTelephonySignalStrength: no service");
+ if (Settings.System.getInt(mContext.getContentResolver(),
+ Settings.System.AIRPLANE_MODE_ON, 0) == 1) {
+ mPhoneSignalIconId = R.drawable.stat_sys_signal_flightmode;
+ } else {
+ mPhoneSignalIconId = R.drawable.stat_sys_signal_null;
+ }
+ } else {
+ if (isCdma()) {
+ // If 3G(EV) and 1x network are available than 3G should be
+ // displayed, displayed RSSI should be from the EV side.
+ // If a voice call is made then RSSI should switch to 1x.
+ int iconLevel;
+ if ((mPhoneState == TelephonyManager.CALL_STATE_IDLE) && isEvdo()){
+ iconLevel = getEvdoLevel();
+ } else {
+ iconLevel = getCdmaLevel();
+ }
+ int[] iconList;
+ if (isCdmaEri()) {
+ iconList = TelephonyIcons.TELEPHONY_SIGNAL_STRENGTH_ROAMING[mInetCondition];
+ } else {
+ iconList = TelephonyIcons.TELEPHONY_SIGNAL_STRENGTH[mInetCondition];
+ }
+ mPhoneSignalIconId = iconList[iconLevel];
+ } else {
+ int asu = mSignalStrength.getGsmSignalStrength();
+
+ // ASU ranges from 0 to 31 - TS 27.007 Sec 8.5
+ // asu = 0 (-113dB or less) is very weak
+ // signal, its better to show 0 bars to the user in such cases.
+ // asu = 99 is a special case, where the signal strength is unknown.
+ int iconLevel;
+ if (asu <= 2 || asu == 99) iconLevel = 0;
+ else if (asu >= 12) iconLevel = 4;
+ else if (asu >= 8) iconLevel = 3;
+ else if (asu >= 5) iconLevel = 2;
+ else iconLevel = 1;
+
+ // Though mPhone is a Manager, this call is not an IPC
+ int[] iconList;
+ if (mPhone.isNetworkRoaming()) {
+ iconList = TelephonyIcons.TELEPHONY_SIGNAL_STRENGTH_ROAMING[mInetCondition];
+ } else {
+ iconList = TelephonyIcons.TELEPHONY_SIGNAL_STRENGTH[mInetCondition];
+ }
+ mPhoneSignalIconId = iconList[iconLevel];
+ }
+ }
+ }
+
+ private final void updateDataNetType(int net) {
+ switch (net) {
+ case TelephonyManager.NETWORK_TYPE_EDGE:
+ mDataIconList = TelephonyIcons.DATA_E[mInetCondition];
+ break;
+ case TelephonyManager.NETWORK_TYPE_UMTS:
+ mDataIconList = TelephonyIcons.DATA_3G[mInetCondition];
+ break;
+ case TelephonyManager.NETWORK_TYPE_HSDPA:
+ case TelephonyManager.NETWORK_TYPE_HSUPA:
+ case TelephonyManager.NETWORK_TYPE_HSPA:
+ if (mHspaDataDistinguishable) {
+ mDataIconList = TelephonyIcons.DATA_H[mInetCondition];
+ } else {
+ mDataIconList = TelephonyIcons.DATA_3G[mInetCondition];
+ }
+ break;
+ case TelephonyManager.NETWORK_TYPE_CDMA:
+ // display 1xRTT for IS95A/B
+ mDataIconList = TelephonyIcons.DATA_1X[mInetCondition];
+ break;
+ case TelephonyManager.NETWORK_TYPE_1xRTT:
+ mDataIconList = TelephonyIcons.DATA_1X[mInetCondition];
+ break;
+ case TelephonyManager.NETWORK_TYPE_EVDO_0: //fall through
+ case TelephonyManager.NETWORK_TYPE_EVDO_A:
+ case TelephonyManager.NETWORK_TYPE_EVDO_B:
+ mDataIconList = TelephonyIcons.DATA_3G[mInetCondition];
+ break;
+ // TODO - add support for NETWORK_TYPE_LTE and NETWORK_TYPE_EHRPD
+ default:
+ mDataIconList = TelephonyIcons.DATA_G[mInetCondition];
+ break;
+ }
+ }
+
+ boolean isCdmaEri() {
+ final int iconIndex = mServiceState.getCdmaEriIconIndex();
+ if (iconIndex != EriInfo.ROAMING_INDICATOR_OFF) {
+ final int iconMode = mServiceState.getCdmaEriIconMode();
+ if (iconMode == EriInfo.ROAMING_ICON_MODE_NORMAL
+ || iconMode == EriInfo.ROAMING_ICON_MODE_FLASH) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ private final void updateDataIcon() {
+ int iconId;
+ boolean visible = true;
+
+ if (!isCdma()) {
+ // GSM case, we have to check also the sim state
+ if (mSimState == IccCard.State.READY || mSimState == IccCard.State.UNKNOWN) {
+ if (hasService() && mDataState == TelephonyManager.DATA_CONNECTED) {
+ switch (mDataActivity) {
+ case TelephonyManager.DATA_ACTIVITY_IN:
+ iconId = mDataIconList[1];
+ break;
+ case TelephonyManager.DATA_ACTIVITY_OUT:
+ iconId = mDataIconList[2];
+ break;
+ case TelephonyManager.DATA_ACTIVITY_INOUT:
+ iconId = mDataIconList[3];
+ break;
+ default:
+ iconId = mDataIconList[0];
+ break;
+ }
+ mDataIconId = iconId;
+ } else {
+ iconId = 0;
+ visible = false;
+ }
+ } else {
+ iconId = R.drawable.stat_sys_no_sim;
+ }
+ } else {
+ // CDMA case, mDataActivity can be also DATA_ACTIVITY_DORMANT
+ if (hasService() && mDataState == TelephonyManager.DATA_CONNECTED) {
+ switch (mDataActivity) {
+ case TelephonyManager.DATA_ACTIVITY_IN:
+ iconId = mDataIconList[1];
+ break;
+ case TelephonyManager.DATA_ACTIVITY_OUT:
+ iconId = mDataIconList[2];
+ break;
+ case TelephonyManager.DATA_ACTIVITY_INOUT:
+ iconId = mDataIconList[3];
+ break;
+ case TelephonyManager.DATA_ACTIVITY_DORMANT:
+ default:
+ iconId = mDataIconList[0];
+ break;
+ }
+ } else {
+ iconId = 0;
+ visible = false;
+ }
+ }
+
+ // yuck - this should NOT be done by the status bar
+ long ident = Binder.clearCallingIdentity();
+ try {
+ mBatteryStats.notePhoneDataConnectionState(mPhone.getNetworkType(), visible);
+ } catch (RemoteException e) {
+ } finally {
+ Binder.restoreCallingIdentity(ident);
+ }
+
+ mDataIconId = iconId;
+ mDataConnected = visible;
+ }
+
+ // ===== Wifi ===================================================================
+
+ private void updateWifiState(Intent intent) {
+ final String action = intent.getAction();
+ if (action.equals(WifiManager.WIFI_STATE_CHANGED_ACTION)) {
+ mWifiEnabled = intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE,
+ WifiManager.WIFI_STATE_UNKNOWN) == WifiManager.WIFI_STATE_ENABLED;
+
+ } else if (action.equals(WifiManager.NETWORK_STATE_CHANGED_ACTION)
+ || action.equals(WifiManager.SUPPLICANT_STATE_CHANGED_ACTION)) {
+ final NetworkInfo networkInfo = (NetworkInfo)
+ intent.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO);
+ boolean wasConnected = mWifiConnected;
+ mWifiConnected = networkInfo != null && networkInfo.isConnected();
+ // If we just connected, grab the inintial signal strength and ssid
+ if (mWifiConnected && !wasConnected) {
+ WifiInfo info = mWifiManager.getConnectionInfo();
+ if (info != null) {
+ mWifiLevel = WifiManager.calculateSignalLevel(info.getRssi(), 101);
+ mWifiSsid = huntForSsid(info);
+ } else {
+ mWifiLevel = 0;
+ mWifiSsid = null;
+ }
+ } else if (!mWifiConnected) {
+ mWifiLevel = 0;
+ mWifiSsid = null;
+ }
+
+ } else if (action.equals(WifiManager.RSSI_CHANGED_ACTION)) {
+ if (mWifiConnected) {
+ final int newRssi = intent.getIntExtra(WifiManager.EXTRA_NEW_RSSI, -200);
+ mWifiLevel = WifiManager.calculateSignalLevel(newRssi, 101);
+ }
+ }
+
+ updateWifiIcons();
+ }
+
+ private void updateWifiIcons() {
+ if (mWifiConnected) {
+ mWifiIconId = WifiIcons.WIFI_SIGNAL_STRENGTH[mInetCondition][mWifiLevel];
+ } else {
+ mWifiIconId = WifiIcons.WIFI_SIGNAL_STRENGTH[0][0];
+ }
+ }
+
+ private String huntForSsid(WifiInfo info) {
+ String ssid = info.getSSID();
+ if (ssid != null) {
+ return ssid;
+ }
+ // OK, it's not in the connectionInfo; we have to go hunting for it
+ List<WifiConfiguration> networks = mWifiManager.getConfiguredNetworks();
+ for (WifiConfiguration net : networks) {
+ if (net.networkId == info.getNetworkId()) {
+ return net.SSID;
+ }
+ }
+ return null;
+ }
+
+
+ // ===== Full or limited Internet connectivity ==================================
+
+ private void updateConnectivity(Intent intent) {
+ NetworkInfo info = (NetworkInfo)(intent.getParcelableExtra(
+ ConnectivityManager.EXTRA_NETWORK_INFO));
+ int connectionStatus = intent.getIntExtra(ConnectivityManager.EXTRA_INET_CONDITION, 0);
+
+ int inetCondition = (connectionStatus > INET_CONDITION_THRESHOLD ? 1 : 0);
+
+ switch (info.getType()) {
+ case ConnectivityManager.TYPE_MOBILE:
+ mInetCondition = inetCondition;
+ updateDataNetType(info.getSubtype());
+ updateDataIcon();
+ updateTelephonySignalStrength(); // apply any change in connectionStatus
+ break;
+ case ConnectivityManager.TYPE_WIFI:
+ mInetCondition = inetCondition;
+ updateWifiIcons();
+ break;
+ }
+ }
+
+
+ // ===== Update the views =======================================================
+
+ // figure out what to show: first wifi, then 3G, then nothing
+ void refreshViews() {
+ Context context = mContext;
+
+ int combinedDataIconId;
+ String label;
+
+ if (mWifiConnected) {
+ if (mWifiSsid == null) {
+ label = context.getString(R.string.system_panel_signal_meter_wifi_nossid);
+ } else {
+ label = context.getString(R.string.system_panel_signal_meter_wifi_ssid_format,
+ mWifiSsid);
+ }
+ combinedDataIconId = mWifiIconId;
+ } else if (mDataConnected) {
+ label = context.getString(R.string.system_panel_signal_meter_data_connected);
+ combinedDataIconId = mDataIconId;
+ } else {
+ label = context.getString(R.string.system_panel_signal_meter_disconnected);
+ combinedDataIconId = 0;
+ }
+
+ int N;
+
+ if (mLastPhoneSignalIconId != mPhoneSignalIconId) {
+ mLastPhoneSignalIconId = mPhoneSignalIconId;
+ N = mPhoneIconViews.size();
+ for (int i=0; i<N; i++) {
+ ImageView v = mPhoneIconViews.get(i);
+ v.setImageResource(mPhoneSignalIconId);
+ }
+ }
+
+ if (mLastCombinedDataIconId != combinedDataIconId) {
+ mLastCombinedDataIconId = combinedDataIconId;
+ N = mDataIconViews.size();
+ for (int i=0; i<N; i++) {
+ ImageView v = mDataIconViews.get(i);
+ v.setImageResource(combinedDataIconId);
+ }
+ }
+
+ if (!mLastLabel.equals(label)) {
+ mLastLabel = label;
+ N = mLabelViews.size();
+ for (int i=0; i<N; i++) {
+ TextView v = mLabelViews.get(i);
+ v.setText(label);
+ }
+ }
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/TelephonyIcons.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/TelephonyIcons.java
new file mode 100644
index 0000000..050a746
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/TelephonyIcons.java
@@ -0,0 +1,113 @@
+/*
+ * 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.systemui.statusbar.policy;
+
+import com.android.systemui.R;
+
+class TelephonyIcons {
+ //***** Signal strength icons
+
+ //GSM/UMTS
+ static final int[][] TELEPHONY_SIGNAL_STRENGTH = {
+ { R.drawable.stat_sys_signal_0,
+ R.drawable.stat_sys_signal_1,
+ R.drawable.stat_sys_signal_2,
+ R.drawable.stat_sys_signal_3,
+ R.drawable.stat_sys_signal_4 },
+ { R.drawable.stat_sys_signal_0_fully,
+ R.drawable.stat_sys_signal_1_fully,
+ R.drawable.stat_sys_signal_2_fully,
+ R.drawable.stat_sys_signal_3_fully,
+ R.drawable.stat_sys_signal_4_fully }
+ };
+
+ static final int[][] TELEPHONY_SIGNAL_STRENGTH_ROAMING = {
+ { R.drawable.stat_sys_r_signal_0,
+ R.drawable.stat_sys_r_signal_1,
+ R.drawable.stat_sys_r_signal_2,
+ R.drawable.stat_sys_r_signal_3,
+ R.drawable.stat_sys_r_signal_4 },
+ { R.drawable.stat_sys_r_signal_0_fully,
+ R.drawable.stat_sys_r_signal_1_fully,
+ R.drawable.stat_sys_r_signal_2_fully,
+ R.drawable.stat_sys_r_signal_3_fully,
+ R.drawable.stat_sys_r_signal_4_fully }
+ };
+
+ //***** Data connection icons
+
+ //GSM/UMTS
+ static final int[][] DATA_G = {
+ { R.drawable.stat_sys_data_connected_g,
+ R.drawable.stat_sys_data_in_g,
+ R.drawable.stat_sys_data_out_g,
+ R.drawable.stat_sys_data_inandout_g },
+ { R.drawable.stat_sys_data_fully_connected_g,
+ R.drawable.stat_sys_data_fully_in_g,
+ R.drawable.stat_sys_data_fully_out_g,
+ R.drawable.stat_sys_data_fully_inandout_g }
+ };
+
+ static final int[][] DATA_3G = {
+ { R.drawable.stat_sys_data_connected_3g,
+ R.drawable.stat_sys_data_in_3g,
+ R.drawable.stat_sys_data_out_3g,
+ R.drawable.stat_sys_data_inandout_3g },
+ { R.drawable.stat_sys_data_fully_connected_3g,
+ R.drawable.stat_sys_data_fully_in_3g,
+ R.drawable.stat_sys_data_fully_out_3g,
+ R.drawable.stat_sys_data_fully_inandout_3g }
+ };
+
+ static final int[][] DATA_E = {
+ { R.drawable.stat_sys_data_connected_e,
+ R.drawable.stat_sys_data_in_e,
+ R.drawable.stat_sys_data_out_e,
+ R.drawable.stat_sys_data_inandout_e },
+ { R.drawable.stat_sys_data_fully_connected_e,
+ R.drawable.stat_sys_data_fully_in_e,
+ R.drawable.stat_sys_data_fully_out_e,
+ R.drawable.stat_sys_data_fully_inandout_e }
+ };
+
+ //3.5G
+ static final int[][] DATA_H = {
+ { R.drawable.stat_sys_data_connected_h,
+ R.drawable.stat_sys_data_in_h,
+ R.drawable.stat_sys_data_out_h,
+ R.drawable.stat_sys_data_inandout_h },
+ { R.drawable.stat_sys_data_fully_connected_h,
+ R.drawable.stat_sys_data_fully_in_h,
+ R.drawable.stat_sys_data_fully_out_h,
+ R.drawable.stat_sys_data_fully_inandout_h }
+ };
+
+ //CDMA
+ // Use 3G icons for EVDO data and 1x icons for 1XRTT data
+ static final int[][] DATA_1X = {
+ { R.drawable.stat_sys_data_connected_1x,
+ R.drawable.stat_sys_data_in_1x,
+ R.drawable.stat_sys_data_out_1x,
+ R.drawable.stat_sys_data_inandout_1x },
+ { R.drawable.stat_sys_data_fully_connected_1x,
+ R.drawable.stat_sys_data_fully_in_1x,
+ R.drawable.stat_sys_data_fully_out_1x,
+ R.drawable.stat_sys_data_fully_inandout_1x }
+ };
+
+}
+
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/WifiIcons.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/WifiIcons.java
new file mode 100644
index 0000000..d218ebf
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/WifiIcons.java
@@ -0,0 +1,32 @@
+/*
+ * 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.systemui.statusbar.policy;
+
+import com.android.systemui.R;
+
+class WifiIcons {
+ static final int[][] WIFI_SIGNAL_STRENGTH = {
+ { R.drawable.stat_sys_wifi_signal_1,
+ R.drawable.stat_sys_wifi_signal_2,
+ R.drawable.stat_sys_wifi_signal_3,
+ R.drawable.stat_sys_wifi_signal_4 },
+ { R.drawable.stat_sys_wifi_signal_1_fully,
+ R.drawable.stat_sys_wifi_signal_2_fully,
+ R.drawable.stat_sys_wifi_signal_3_fully,
+ R.drawable.stat_sys_wifi_signal_4_fully }
+ };
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/NotificationPanel.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/NotificationPanel.java
index eee0a16..1a08f22 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/NotificationPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/NotificationPanel.java
@@ -17,11 +17,14 @@
package com.android.systemui.statusbar.tablet;
import android.content.Context;
-import android.widget.LinearLayout;
import android.util.AttributeSet;
+import android.widget.ImageView;
+import android.widget.RelativeLayout;
+import android.widget.TextView;
-public class NotificationPanel extends LinearLayout implements StatusBarPanel {
+import com.android.systemui.R;
+public class NotificationPanel extends RelativeLayout implements StatusBarPanel {
public NotificationPanel(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/RecentAppsPanel.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/RecentAppsPanel.java
index 3d4d42c..e0b05f9 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/RecentAppsPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/RecentAppsPanel.java
@@ -45,11 +45,11 @@
public class RecentAppsPanel extends LinearLayout implements StatusBarPanel, OnClickListener {
private static final String TAG = "RecentAppsPanel";
- private static final boolean DEBUG = TabletStatusBarService.DEBUG;
+ private static final boolean DEBUG = TabletStatusBar.DEBUG;
private static final int DISPLAY_TASKS = 4; // number of recent tasks to display
private static final int MAX_TASKS = 2 * DISPLAY_TASKS; // give some slack for non-apps
private static final boolean DBG = true;
- private TabletStatusBarService mBar;
+ private TabletStatusBar mBar;
private TextView mNoRecents;
private LinearLayout mRecentsContainer;
private ArrayList<ActivityDescription> mActivityDescriptions;
@@ -100,7 +100,7 @@
return x >= l && x < r && y >= t && y < b;
}
- public void setBar(TabletStatusBarService bar) {
+ public void setBar(TabletStatusBar bar) {
mBar = bar;
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/ShirtPocket.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/ShirtPocket.java
index 09c8cd2..0cb9249 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/ShirtPocket.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/ShirtPocket.java
@@ -206,7 +206,7 @@
// lp.x = pos[1];
// lp.y = 0;
lp.setTitle("ShirtPocket");
- lp.windowAnimations = com.android.internal.R.style.Animation_SlidingCard;
+ lp.windowAnimations = R.style.Animation_ShirtPocketPanel;
WindowManagerImpl.getDefault().addView(mWindow, lp);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/SystemPanel.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/SystemPanel.java
index c9a8d56..41b44c2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/SystemPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/SystemPanel.java
@@ -16,60 +16,31 @@
package com.android.systemui.statusbar.tablet;
-import android.app.Notification;
-import android.app.PendingIntent;
-import android.app.Service;
-import android.app.StatusBarManager;
import android.bluetooth.BluetoothAdapter;
import android.content.BroadcastReceiver;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
-import android.content.res.Resources;
-import android.graphics.PixelFormat;
-import android.graphics.Rect;
import android.location.LocationManager;
import android.media.AudioManager;
-import android.net.NetworkInfo;
-import android.net.wifi.SupplicantState;
-import android.net.wifi.WifiConfiguration;
-import android.net.wifi.WifiInfo;
-import android.net.wifi.WifiManager;
-import android.os.AsyncTask;
-import android.os.Handler;
-import android.os.IBinder;
+import android.telephony.PhoneStateListener;
+import android.telephony.ServiceState;
import android.os.IPowerManager;
-import android.os.Message;
-import android.os.RemoteException;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.provider.Settings;
-import android.telephony.PhoneStateListener;
-import android.telephony.ServiceState;
-import android.telephony.SignalStrength;
-import android.telephony.TelephonyManager;
import android.util.AttributeSet;
import android.util.Slog;
-import android.view.Gravity;
-import android.view.LayoutInflater;
import android.view.View;
-import android.view.ViewGroup;
import android.view.IWindowManager;
import android.view.WindowManager;
import android.view.WindowManagerImpl;
-import android.widget.Button;
import android.widget.ImageButton;
-import android.widget.ImageView;
import android.widget.LinearLayout;
-import android.widget.RemoteViews;
-import android.widget.ScrollView;
-import android.widget.TextSwitcher;
import android.widget.TextView;
import android.widget.Toast;
-import java.util.List;
-
import com.android.internal.telephony.IccCard;
import com.android.internal.telephony.TelephonyIntents;
import com.android.internal.telephony.cdma.EriInfo;
@@ -82,14 +53,13 @@
public class SystemPanel extends LinearLayout implements StatusBarPanel {
private static final String TAG = "SystemPanel";
- private static final boolean DEBUG = TabletStatusBarService.DEBUG;
- private static final boolean DEBUG_SIGNAL = false;
+ private static final boolean DEBUG = TabletStatusBar.DEBUG;
private static final int MINIMUM_BACKLIGHT = android.os.Power.BRIGHTNESS_DIM + 5;
private static final int MAXIMUM_BACKLIGHT = android.os.Power.BRIGHTNESS_ON;
private static final int DEFAULT_BACKLIGHT = (int) (android.os.Power.BRIGHTNESS_ON * 0.4f);
- private TabletStatusBarService mBar;
+ private TabletStatusBar mBar;
private boolean mAirplaneMode;
private ImageButton mBrightnessButton;
@@ -99,34 +69,11 @@
private ImageButton mGpsButton;
private ImageButton mBluetoothButton;
- private ImageView mBatteryMeter;
- private ImageView mSignalMeter;
-
- private TextView mBatteryText;
- private TextView mSignalText;
-
private final IWindowManager mWM;
private final AudioManager mAudioManager;
- private final WifiManager mWifiManager;
- private final TelephonyManager mPhone;
private final BluetoothAdapter mBluetoothAdapter;
- // state trackers for telephony code
- IccCard.State mSimState = IccCard.State.READY;
- int mPhoneState = TelephonyManager.CALL_STATE_IDLE;
- int mDataState = TelephonyManager.DATA_DISCONNECTED;
- ServiceState mServiceState;
- SignalStrength mSignalStrength;
-
- // state for the meters
- boolean mWifiEnabled, mWifiConnected;
- int mWifiLevel;
- String mWifiSsid;
-
- boolean mDataEnabled, mDataConnected, mDataRoaming;
- int mDataLevel;
-
public boolean isInContentArea(int x, int y) {
final int l = getPaddingLeft();
final int r = getWidth() - getPaddingRight();
@@ -141,260 +88,16 @@
final String action = intent.getAction();
if (action.equals(AudioManager.RINGER_MODE_CHANGED_ACTION)) {
refreshSound();
- } else if (action.equals(Intent.ACTION_BATTERY_CHANGED)) {
- updateBattery(intent);
- } else if (action.equals(WifiManager.RSSI_CHANGED_ACTION)
- || action.equals(WifiManager.WIFI_STATE_CHANGED_ACTION)
- || action.equals(WifiManager.SUPPLICANT_STATE_CHANGED_ACTION)
- || action.equals(WifiManager.NETWORK_STATE_CHANGED_ACTION)) {
- updateWifiState(intent);
- } else if (action.equals(TelephonyIntents.ACTION_SIM_STATE_CHANGED)) {
- updateSimState(intent);
} else if (action.equals(BluetoothAdapter.ACTION_STATE_CHANGED)) {
refreshBluetooth();
}
}
};
- private final void updateSimState(Intent intent) {
- String stateExtra = intent.getStringExtra(IccCard.INTENT_KEY_ICC_STATE);
- if (IccCard.INTENT_VALUE_ICC_ABSENT.equals(stateExtra)) {
- mSimState = IccCard.State.ABSENT;
- }
- else if (IccCard.INTENT_VALUE_ICC_READY.equals(stateExtra)) {
- mSimState = IccCard.State.READY;
- }
- else if (IccCard.INTENT_VALUE_ICC_LOCKED.equals(stateExtra)) {
- final String lockedReason = intent.getStringExtra(IccCard.INTENT_KEY_LOCKED_REASON);
- if (IccCard.INTENT_VALUE_LOCKED_ON_PIN.equals(lockedReason)) {
- mSimState = IccCard.State.PIN_REQUIRED;
- }
- else if (IccCard.INTENT_VALUE_LOCKED_ON_PUK.equals(lockedReason)) {
- mSimState = IccCard.State.PUK_REQUIRED;
- }
- else {
- mSimState = IccCard.State.NETWORK_LOCKED;
- }
- } else {
- mSimState = IccCard.State.UNKNOWN;
- }
- updateDataState();
- }
-
- private boolean isCdma() {
- return (mSignalStrength != null) && !mSignalStrength.isGsm();
- }
-
- private boolean isEvdo() {
- return ( (mServiceState != null)
- && ((mServiceState.getRadioTechnology()
- == ServiceState.RADIO_TECHNOLOGY_EVDO_0)
- || (mServiceState.getRadioTechnology()
- == ServiceState.RADIO_TECHNOLOGY_EVDO_A)
- || (mServiceState.getRadioTechnology()
- == ServiceState.RADIO_TECHNOLOGY_EVDO_B)));
- }
-
- private boolean hasService() {
- if (mServiceState != null) {
- switch (mServiceState.getState()) {
- case ServiceState.STATE_OUT_OF_SERVICE:
- case ServiceState.STATE_POWER_OFF:
- return false;
- default:
- return true;
- }
- } else {
- return false;
- }
- }
-
- private int getCdmaLevel() {
- if (mSignalStrength == null) return 0;
- final int cdmaDbm = mSignalStrength.getCdmaDbm();
- final int cdmaEcio = mSignalStrength.getCdmaEcio();
- int levelDbm = 0;
- int levelEcio = 0;
-
- if (cdmaDbm >= -75) levelDbm = 4;
- else if (cdmaDbm >= -85) levelDbm = 3;
- else if (cdmaDbm >= -95) levelDbm = 2;
- else if (cdmaDbm >= -100) levelDbm = 1;
- else levelDbm = 0;
-
- // Ec/Io are in dB*10
- if (cdmaEcio >= -90) levelEcio = 4;
- else if (cdmaEcio >= -110) levelEcio = 3;
- else if (cdmaEcio >= -130) levelEcio = 2;
- else if (cdmaEcio >= -150) levelEcio = 1;
- else levelEcio = 0;
-
- return (levelDbm < levelEcio) ? levelDbm : levelEcio;
- }
-
- private int getEvdoLevel() {
- if (mSignalStrength == null) return 0;
- int evdoDbm = mSignalStrength.getEvdoDbm();
- int evdoSnr = mSignalStrength.getEvdoSnr();
- int levelEvdoDbm = 0;
- int levelEvdoSnr = 0;
-
- if (evdoDbm >= -65) levelEvdoDbm = 4;
- else if (evdoDbm >= -75) levelEvdoDbm = 3;
- else if (evdoDbm >= -90) levelEvdoDbm = 2;
- else if (evdoDbm >= -105) levelEvdoDbm = 1;
- else levelEvdoDbm = 0;
-
- if (evdoSnr >= 7) levelEvdoSnr = 4;
- else if (evdoSnr >= 5) levelEvdoSnr = 3;
- else if (evdoSnr >= 3) levelEvdoSnr = 2;
- else if (evdoSnr >= 1) levelEvdoSnr = 1;
- else levelEvdoSnr = 0;
-
- return (levelEvdoDbm < levelEvdoSnr) ? levelEvdoDbm : levelEvdoSnr;
- }
-
- private void updateDataState() {
- mDataConnected = hasService() && (mDataState == TelephonyManager.DATA_CONNECTED);
-
- if (isCdma()) {
- // these functions return a value from 0 to 4, inclusive
- if ((mPhoneState == TelephonyManager.CALL_STATE_IDLE) && isEvdo()){
- mDataLevel = getEvdoLevel() * 25;
- } else {
- mDataLevel = getCdmaLevel() * 25;
- }
- } else {
- // GSM
-
- int asu = (mSignalStrength == null) ? 0 : mSignalStrength.getGsmSignalStrength();
-
- // asu on [0,31]; 99 = unknown
- // Android has historically shown anything >=12 as "full"
- // XXX: tune this based on Industry Best Practices(TM)
- if (asu <= 2 || asu == 99) mDataLevel = 0;
- else mDataLevel = (int)(((float)Math.max(asu, 15) / 15) * 100);
-
- mDataRoaming = mPhone.isNetworkRoaming();
-
- mDataConnected = mDataConnected
- && (mSimState == IccCard.State.READY || mSimState == IccCard.State.UNKNOWN);
- }
-
- if (DEBUG_SIGNAL || DEBUG) {
- Slog.d(TAG, "updateDataState: connected=" + mDataConnected
- + " level=" + mDataLevel
- + " isEvdo=" + isEvdo()
- + " isCdma=" + isCdma()
- + " mPhoneState=" + mPhoneState
- + " mDataState=" + mDataState
- );
- }
-
- refreshSignalMeters();
- }
-
- private void updateWifiState(Intent intent) {
- if (DEBUG)
- Slog.d(TAG, "updateWifiState: " + intent);
-
- final String action = intent.getAction();
- final boolean wasConnected = mWifiConnected;
-
- if (action.equals(WifiManager.WIFI_STATE_CHANGED_ACTION)) {
- mWifiEnabled = intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE,
- WifiManager.WIFI_STATE_UNKNOWN) == WifiManager.WIFI_STATE_ENABLED;
- } else if (action.equals(WifiManager.NETWORK_STATE_CHANGED_ACTION)) {
- final NetworkInfo networkInfo = (NetworkInfo)
- intent.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO);
- mWifiConnected = networkInfo != null && networkInfo.isConnected();
- } else if (action.equals(WifiManager.SUPPLICANT_STATE_CHANGED_ACTION)) {
- final NetworkInfo.DetailedState detailedState = WifiInfo.getDetailedStateOf(
- (SupplicantState)intent.getParcelableExtra(WifiManager.EXTRA_NEW_STATE));
- mWifiConnected = detailedState == NetworkInfo.DetailedState.CONNECTED;
- } else if (action.equals(WifiManager.RSSI_CHANGED_ACTION)) {
- final int newRssi = intent.getIntExtra(WifiManager.EXTRA_NEW_RSSI, -200);
- int newSignalLevel = WifiManager.calculateSignalLevel(newRssi, 101);
- mWifiLevel = mWifiConnected ? newSignalLevel : 0;
- }
-
- if (mWifiConnected && !wasConnected) {
- WifiInfo info = mWifiManager.getConnectionInfo();
- if (DEBUG)
- Slog.d(TAG, "updateWifiState: just connected: info=" + info);
-
- if (info != null) {
- // grab the initial signal strength
- mWifiLevel = WifiManager.calculateSignalLevel(info.getRssi(), 101);
-
- // find the SSID
- mWifiSsid = info.getSSID();
- if (mWifiSsid == null) {
- // OK, it's not in the connectionInfo; we have to go hunting for it
- List<WifiConfiguration> networks = mWifiManager.getConfiguredNetworks();
- for (WifiConfiguration net : networks) {
- if (net.networkId == info.getNetworkId()) {
- mWifiSsid = net.SSID;
- break;
- }
- }
- }
- }
- }
-
- refreshSignalMeters();
- }
-
- // figure out what to show: first wifi, then 3G, then nothing
- void refreshSignalMeters() {
- if (mSignalMeter == null) return; // no UI yet
-
- Context ctxt = getContext();
-
- String text = null;
- int level = 0;
-
- if (mWifiConnected) {
- if (mWifiSsid == null) {
- text = ctxt.getString(R.string.system_panel_signal_meter_wifi_nossid);
- } else {
- text = ctxt.getString(R.string.system_panel_signal_meter_wifi_ssid_format,
- mWifiSsid);
- }
- level = mWifiLevel;
- } else if (mDataConnected) {
- text = ctxt.getString(R.string.system_panel_signal_meter_data_connected);
- level = mDataLevel;
- } else {
- text = ctxt.getString(R.string.system_panel_signal_meter_disconnected);
- level = 0;
- }
-
- mSignalMeter.setImageResource(R.drawable.sysbar_signal);
- mSignalMeter.setImageLevel(level);
- mSignalText.setText(text);
-
- // hack for now
- mBar.setSignalMeter(level, mWifiConnected);
- }
-
- public void setBar(TabletStatusBarService bar) {
+ public void setBar(TabletStatusBar bar) {
mBar = bar;
}
- public void updateBattery(Intent intent) {
- final int level = intent.getIntExtra("level", 0);
- final boolean plugged = intent.getIntExtra("plugged", 0) != 0;
-
- mBatteryMeter.setImageResource(R.drawable.sysbar_battery);
- mBatteryMeter.setImageLevel(level);
- mBatteryText.setText(getContext()
- .getString(R.string.system_panel_battery_meter_format, level));
-
- // hack for now
- mBar.setBatteryMeter(level, plugged);
- }
-
public SystemPanel(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
@@ -406,34 +109,14 @@
mWM = IWindowManager.Stub.asInterface(
ServiceManager.getService("window"));
-
- // get notified of phone state changes
- TelephonyManager telephonyManager =
- (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
- telephonyManager.listen(mPhoneStateListener,
- PhoneStateListener.LISTEN_SERVICE_STATE
- | PhoneStateListener.LISTEN_SIGNAL_STRENGTHS
- | PhoneStateListener.LISTEN_CALL_STATE
- | PhoneStateListener.LISTEN_DATA_CONNECTION_STATE
- | PhoneStateListener.LISTEN_DATA_ACTIVITY);
-
- // wifi status info
- mWifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
-
// audio status
mAudioManager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
- // mobile data
- mPhone = (TelephonyManager)context.getSystemService(Context.TELEPHONY_SERVICE);
-
// Bluetooth
mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
}
public void onAttachedToWindow() {
- DateView date = (DateView)findViewById(R.id.date);
- date.setUpdates(true);
-
TextView settingsButton = (TextView)findViewById(R.id.settings_button);
settingsButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
@@ -508,26 +191,9 @@
// register for broadcasts
IntentFilter filter = new IntentFilter();
filter.addAction(AudioManager.RINGER_MODE_CHANGED_ACTION);
- filter.addAction(Intent.ACTION_BATTERY_CHANGED);
- filter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION);
- filter.addAction(WifiManager.SUPPLICANT_STATE_CHANGED_ACTION);
- filter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION);
- filter.addAction(WifiManager.RSSI_CHANGED_ACTION);
- filter.addAction(TelephonyIntents.ACTION_SIM_STATE_CHANGED);
filter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);
getContext().registerReceiver(mReceiver, filter);
- mBatteryMeter = (ImageView)findViewById(R.id.battery_meter);
- mBatteryMeter.setImageResource(R.drawable.sysbar_battery);
- mBatteryMeter.setImageLevel(0);
- mSignalMeter = (ImageView)findViewById(R.id.signal_meter);
- mBatteryMeter.setImageResource(R.drawable.sysbar_signal);
- mBatteryMeter.setImageLevel(0);
-
- mBatteryText = (TextView)findViewById(R.id.battery_info);
- mSignalText = (TextView)findViewById(R.id.signal_info);
-
- refreshSignalMeters();
refreshBluetooth();
refreshGps();
}
@@ -615,10 +281,9 @@
PhoneStateListener mPhoneStateListener = new PhoneStateListener() {
@Override
public void onServiceStateChanged(ServiceState serviceState) {
- if (DEBUG_SIGNAL || DEBUG) {
+ if (DEBUG) {
Slog.d(TAG, "phone service state changed: " + serviceState.getState());
}
- mServiceState = serviceState;
mAirplaneMode = serviceState.getState() == ServiceState.STATE_POWER_OFF;
if (mAirplaneButton != null) {
mAirplaneButton.setImageResource(mAirplaneMode
@@ -628,34 +293,6 @@
? R.drawable.sysbar_toggle_bg_on
: R.drawable.sysbar_toggle_bg_off);
}
- updateDataState();
- }
- @Override
- public void onSignalStrengthsChanged(SignalStrength signalStrength) {
- if (DEBUG_SIGNAL || DEBUG) {
- Slog.d(TAG, "onSignalStrengthsChanged: " + signalStrength);
- }
- mSignalStrength = signalStrength;
- updateDataState();
- }
- @Override
- public void onCallStateChanged(int state, String incomingNumber) {
- mPhoneState = state;
- // In cdma, if a voice call is made, RSSI should switch to 1x.
- if (isCdma()) {
- updateDataState();
- }
- }
-
- @Override
- public void onDataConnectionStateChanged(int state, int networkType) {
- if (DEBUG_SIGNAL || DEBUG) {
- Slog.d(TAG, "onDataConnectionStateChanged: state=" + state
- + " type=" + networkType);
- }
- mDataState = state;
-// updateDataNetType(networkType);
- updateDataState();
}
};
@@ -745,7 +382,7 @@
} else {
mWM.freezeRotation();
}
- } catch (android.os.RemoteException exc) {
+ } catch (RemoteException exc) {
}
}
@@ -759,7 +396,7 @@
int getDisplayRotation() {
try {
return mWM.getRotation();
- } catch (android.os.RemoteException exc) {
+ } catch (RemoteException exc) {
return 0;
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBarService.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java
similarity index 79%
rename from packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBarService.java
rename to packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java
index da44f43..2efdf96 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBarService.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java
@@ -59,20 +59,20 @@
import com.android.internal.statusbar.StatusBarIcon;
import com.android.internal.statusbar.StatusBarNotification;
-import com.android.systemui.statusbar.*;
-import com.android.systemui.recent.RecentApplicationsActivity;
import com.android.systemui.R;
+import com.android.systemui.statusbar.*;
+import com.android.systemui.statusbar.policy.BatteryController;
+import com.android.systemui.statusbar.policy.NetworkController;
+import com.android.systemui.recent.RecentApplicationsActivity;
-public class TabletStatusBarService extends StatusBarService {
+public class TabletStatusBar extends StatusBar {
public static final boolean DEBUG = false;
- public static final String TAG = "TabletStatusBarService";
+ public static final String TAG = "TabletStatusBar";
public static final int MSG_OPEN_NOTIFICATION_PANEL = 1000;
public static final int MSG_CLOSE_NOTIFICATION_PANEL = 1001;
public static final int MSG_OPEN_NOTIFICATION_PEEK = 1002;
public static final int MSG_CLOSE_NOTIFICATION_PEEK = 1003;
- public static final int MSG_OPEN_SYSTEM_PANEL = 1010;
- public static final int MSG_CLOSE_SYSTEM_PANEL = 1011;
public static final int MSG_OPEN_RECENTS_PANEL = 1020;
public static final int MSG_CLOSE_RECENTS_PANEL = 1021;
public static final int MSG_LIGHTS_ON = 1030;
@@ -89,10 +89,9 @@
private NotificationData mNotns = new NotificationData();
TabletStatusBarView mStatusBarView;
- ImageView mNotificationTrigger;
+ View mNotificationArea;
+ View mNotificationTrigger;
NotificationIconArea mNotificationIconArea;
- View mNotificationButtons;
- View mSystemInfo;
View mNavigationArea;
View mMenuButton;
View mRecentButton;
@@ -100,7 +99,6 @@
InputMethodButton mInputMethodButton;
NotificationPanel mNotificationPanel;
- SystemPanel mSystemPanel;
NotificationPanel mNotificationPeekWindow;
ViewGroup mNotificationPeekRow;
int mNotificationPeekIndex;
@@ -110,12 +108,9 @@
int mNotificationFlingVelocity;
ViewGroup mPile;
- TextView mClearButton;
- TextView mDoNotDisturbButton;
- ImageView mBatteryMeter;
- ImageView mSignalMeter;
- ImageView mSignalIcon;
+ BatteryController mBatteryController;
+ NetworkController mNetworkController;
View mBarContents;
View mCurtains;
@@ -146,6 +141,15 @@
mNotificationPanel.setOnTouchListener(
new TouchOutsideListener(MSG_CLOSE_NOTIFICATION_PANEL, mNotificationPanel));
+ // the battery and network icons
+ mBatteryController.addIconView((ImageView)mNotificationPanel.findViewById(R.id.battery));
+ mBatteryController.addLabelView(
+ (TextView)mNotificationPanel.findViewById(R.id.battery_text));
+ mNetworkController.addCombinedDataIconView(
+ (ImageView)mNotificationPanel.findViewById(R.id.network));
+ mNetworkController.addLabelView(
+ (TextView)mNotificationPanel.findViewById(R.id.network_text));
+
mStatusBarView.setIgnoreChildren(0, mNotificationTrigger, mNotificationPanel);
WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
@@ -158,7 +162,6 @@
PixelFormat.TRANSLUCENT);
lp.gravity = Gravity.BOTTOM | Gravity.RIGHT;
lp.setTitle("NotificationPanel");
- lp.windowAnimations = com.android.internal.R.style.Animation_SlidingCard;
WindowManagerImpl.getDefault().addView(mNotificationPanel, lp);
@@ -198,29 +201,6 @@
WindowManagerImpl.getDefault().addView(mNotificationPeekWindow, lp);
- // System Panel
- mSystemPanel = (SystemPanel) View.inflate(context, R.layout.sysbar_panel_system, null);
- mSystemPanel.setVisibility(View.GONE);
- mSystemPanel.setOnTouchListener(new TouchOutsideListener(MSG_CLOSE_SYSTEM_PANEL,
- mSystemPanel));
- mStatusBarView.setIgnoreChildren(1, mSystemInfo, mSystemPanel);
-
- lp = new WindowManager.LayoutParams(
- 800,
- ViewGroup.LayoutParams.WRAP_CONTENT,
- WindowManager.LayoutParams.TYPE_STATUS_BAR_PANEL,
- WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
- | WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM
- | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH,
- PixelFormat.TRANSLUCENT);
- lp.gravity = Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL;
- lp.setTitle("SystemPanel");
- lp.windowAnimations = com.android.internal.R.style.Animation_SlidingCard;
-
- WindowManagerImpl.getDefault().addView(mSystemPanel, lp);
- mSystemPanel.setBar(this);
-
-
// Recents Panel
if (USE_2D_RECENTS) {
mRecentsPanel = (RecentAppsPanel) View.inflate(context, R.layout.sysbar_panel_recent,
@@ -240,7 +220,7 @@
PixelFormat.TRANSLUCENT);
lp.gravity = Gravity.BOTTOM | Gravity.LEFT;
lp.setTitle("RecentsPanel");
- lp.windowAnimations = com.android.internal.R.style.Animation_SlidingCard;
+ lp.windowAnimations = R.style.Animation_RecentPanel;
WindowManagerImpl.getDefault().addView(mRecentsPanel, lp);
mRecentsPanel.setBar(this);
@@ -266,10 +246,6 @@
mBarContents = sb.findViewById(R.id.bar_contents);
mCurtains = sb.findViewById(R.id.lights_out);
- mSystemInfo = sb.findViewById(R.id.systemInfo);
- mRecentButton = sb.findViewById(R.id.recent_apps);
-
- mSystemInfo.setOnTouchListener(new ClockTouchListener());
mRecentButton = sb.findViewById(R.id.recent_apps);
mRecentButton.setOnClickListener(mOnClickListener);
@@ -278,20 +254,16 @@
mCurtains.setOnClickListener(on);
mCurtains.setOnLongClickListener(on);
+ // the whole right-hand side of the bar
+ mNotificationArea = sb.findViewById(R.id.notificationArea);
+
// the button to open the notification area
- mNotificationTrigger = (ImageView) sb.findViewById(R.id.notificationTrigger);
+ mNotificationTrigger = sb.findViewById(R.id.notificationTrigger);
mNotificationTrigger.setOnClickListener(mOnClickListener);
// the more notifications icon
mNotificationIconArea = (NotificationIconArea)sb.findViewById(R.id.notificationIcons);
- // the clear and dnd buttons
- mNotificationButtons = sb.findViewById(R.id.notificationButtons);
- mClearButton = (TextView)mNotificationButtons.findViewById(R.id.clear_all_button);
- mClearButton.setOnClickListener(mOnClickListener);
- mDoNotDisturbButton = (TextView)mNotificationButtons.findViewById(R.id.do_not_disturb);
- mDoNotDisturbButton.setOnClickListener(mOnClickListener);
-
// where the icons go
mIconLayout = (NotificationIconArea.IconLayout) sb.findViewById(R.id.icons);
mIconLayout.setOnTouchListener(new NotificationIconTouchListener());
@@ -302,10 +274,11 @@
mTicker = new TabletTicker(context, (FrameLayout)sb.findViewById(R.id.ticker));
- // System info (center)
- mBatteryMeter = (ImageView) sb.findViewById(R.id.battery);
- mSignalMeter = (ImageView) sb.findViewById(R.id.signal);
- mSignalIcon = (ImageView) sb.findViewById(R.id.signal_icon);
+ // The icons
+ mBatteryController = new BatteryController(mContext);
+ mBatteryController.addIconView((ImageView)sb.findViewById(R.id.battery));
+ mNetworkController = new NetworkController(mContext);
+ mNetworkController.addCombinedDataIconView((ImageView)sb.findViewById(R.id.network));
// The navigation buttons
mNavigationArea = sb.findViewById(R.id.navigationArea);
@@ -388,36 +361,17 @@
if (mNotificationPanel.getVisibility() == View.GONE) {
mNotificationPeekWindow.setVisibility(View.GONE);
- mDoNotDisturbButton.setText(mNotificationsOn
- ? R.string.status_bar_do_not_disturb_button
- : R.string.status_bar_please_disturb_button);
mNotificationPanel.setVisibility(View.VISIBLE);
- setViewVisibility(mNotificationIconArea, View.GONE,
- R.anim.notification_icons_out);
- setViewVisibility(mNotificationButtons, View.VISIBLE,
- R.anim.notification_buttons_in);
- refreshNotificationTrigger();
+ mNotificationArea.setVisibility(View.GONE);
}
break;
case MSG_CLOSE_NOTIFICATION_PANEL:
if (DEBUG) Slog.d(TAG, "closing notifications panel");
if (mNotificationPanel.getVisibility() == View.VISIBLE) {
mNotificationPanel.setVisibility(View.GONE);
- setViewVisibility(mNotificationIconArea, View.VISIBLE,
- R.anim.notification_icons_in);
- setViewVisibility(mNotificationButtons, View.GONE,
- R.anim.notification_buttons_out);
- refreshNotificationTrigger();
+ mNotificationArea.setVisibility(View.VISIBLE);
}
break;
- case MSG_OPEN_SYSTEM_PANEL:
- if (DEBUG) Slog.d(TAG, "opening system panel");
- mSystemPanel.setVisibility(View.VISIBLE);
- break;
- case MSG_CLOSE_SYSTEM_PANEL:
- if (DEBUG) Slog.d(TAG, "closing system panel");
- mSystemPanel.setVisibility(View.GONE);
- break;
case MSG_OPEN_RECENTS_PANEL:
if (DEBUG) Slog.d(TAG, "opening recents panel");
if (mRecentsPanel != null) mRecentsPanel.setVisibility(View.VISIBLE);
@@ -440,6 +394,7 @@
}
public void refreshNotificationTrigger() {
+ /*
if (mNotificationTrigger == null) return;
int resId;
@@ -452,29 +407,8 @@
} else {
resId = panel ? R.drawable.ic_sysbar_noti_none_open : R.drawable.ic_sysbar_noti_none;
}
- mNotificationTrigger.setImageResource(resId);
- }
-
- public void setBatteryMeter(int level, boolean plugged) {
- if (DEBUG) Slog.d(TAG, "battery=" + level + (plugged ? " - plugged" : " - unplugged"));
- mBatteryMeter.setImageResource(R.drawable.sysbar_batterymini);
- // adjust percent to permyriad for ClipDrawable's sake
- mBatteryMeter.setImageLevel(level * (MAX_IMAGE_LEVEL / 100));
- }
-
- public void setSignalMeter(int level, boolean isWifi) {
- if (DEBUG) Slog.d(TAG, "signal=" + level);
- if (level < 0) {
- mSignalMeter.setImageDrawable(null);
- mSignalMeter.setImageLevel(0);
- mSignalIcon.setImageDrawable(null);
- } else {
- mSignalMeter.setImageResource(R.drawable.sysbar_wifimini);
- // adjust to permyriad
- mSignalMeter.setImageLevel(level * (MAX_IMAGE_LEVEL / 100));
- mSignalIcon.setImageResource(isWifi ? R.drawable.ic_sysbar_wifi_mini
- : R.drawable.ic_sysbar_wifi_mini); // XXX
- }
+ //mNotificationTrigger.setImageResource(resId);
+ */
}
public void addIcon(String slot, int index, int viewIndex, StatusBarIcon icon) {
@@ -599,9 +533,6 @@
public void disable(int state) {
int old = mDisabled;
int diff = state ^ old;
- Slog.d(TAG, "disable... old=0x" + Integer.toHexString(old)
- + " diff=0x" + Integer.toHexString(diff)
- + " state=0x" + Integer.toHexString(state));
mDisabled = state;
// act accordingly
@@ -614,39 +545,24 @@
if ((diff & StatusBarManager.DISABLE_NOTIFICATION_ICONS) != 0) {
if ((state & StatusBarManager.DISABLE_NOTIFICATION_ICONS) != 0) {
Slog.d(TAG, "DISABLE_NOTIFICATION_ICONS: yes");
- setViewVisibility(mNotificationTrigger, View.GONE,
- R.anim.notification_icons_out);
- setViewVisibility(mNotificationIconArea, View.GONE,
- R.anim.notification_icons_out);
+ mNotificationIconArea.setVisibility(View.GONE);
mTicker.halt();
} else {
Slog.d(TAG, "DISABLE_NOTIFICATION_ICONS: no");
- setViewVisibility(mNotificationTrigger, View.VISIBLE,
- R.anim.notification_icons_in);
- setViewVisibility(mNotificationIconArea, View.VISIBLE,
- R.anim.notification_icons_in);
+ mNotificationIconArea.setVisibility(View.VISIBLE);
}
} else if ((diff & StatusBarManager.DISABLE_NOTIFICATION_TICKER) != 0) {
if ((state & StatusBarManager.DISABLE_NOTIFICATION_TICKER) != 0) {
mTicker.halt();
}
}
- if ((diff & StatusBarManager.DISABLE_SYSTEM_INFO) != 0) {
- if ((state & StatusBarManager.DISABLE_SYSTEM_INFO) != 0) {
- Slog.d(TAG, "DISABLE_SYSTEM_INFO: yes");
- setViewVisibility(mSystemInfo, View.GONE, R.anim.navigation_out);
- } else {
- Slog.d(TAG, "DISABLE_SYSTEM_INFO: no");
- setViewVisibility(mSystemInfo, View.VISIBLE, R.anim.navigation_in);
- }
- }
if ((diff & StatusBarManager.DISABLE_NAVIGATION) != 0) {
if ((state & StatusBarManager.DISABLE_NAVIGATION) != 0) {
Slog.d(TAG, "DISABLE_NAVIGATION: yes");
- setViewVisibility(mNavigationArea, View.GONE, R.anim.navigation_out);
+ mNavigationArea.setVisibility(View.GONE);
} else {
Slog.d(TAG, "DISABLE_NAVIGATION: no");
- setViewVisibility(mNavigationArea, View.VISIBLE, R.anim.navigation_in);
+ mNavigationArea.setVisibility(View.VISIBLE);
}
}
}
@@ -682,13 +598,11 @@
public void animateCollapse() {
mHandler.removeMessages(MSG_CLOSE_NOTIFICATION_PANEL);
mHandler.sendEmptyMessage(MSG_CLOSE_NOTIFICATION_PANEL);
- mHandler.removeMessages(MSG_CLOSE_SYSTEM_PANEL);
- mHandler.sendEmptyMessage(MSG_CLOSE_SYSTEM_PANEL);
mHandler.removeMessages(MSG_CLOSE_RECENTS_PANEL);
mHandler.sendEmptyMessage(MSG_CLOSE_RECENTS_PANEL);
}
- // called by StatusBarService
+ // called by StatusBar
@Override
public void setLightsOn(boolean on) {
mHandler.removeMessages(MSG_LIGHTS_OUT);
@@ -700,9 +614,7 @@
if (DEBUG) {
Slog.d(TAG, (visible?"showing":"hiding") + " the MENU button");
}
- setViewVisibility(mMenuButton,
- visible ? View.VISIBLE : View.INVISIBLE,
- visible ? R.anim.navigation_in : R.anim.navigation_out);
+ mMenuButton.setVisibility(visible ? View.VISIBLE : View.INVISIBLE);
}
public void setIMEButtonVisible(boolean visible) {
@@ -717,24 +629,6 @@
//Slog.d(TAG, "setAreThereNotifications hasClerable=" + hasClearable);
- // Show or hide the "Clear all" button. Note that we don't do an animation
- // if it's not on screen, so that if someone opens the bar right then they
- // don't see the animation in progress.
- // (no ongoing notifications are clearable)
- if (hasClearable) {
- if (mNotificationButtons.getVisibility() == View.VISIBLE) {
- setViewVisibility(mClearButton, View.VISIBLE, R.anim.notification_buttons_in);
- } else {
- mClearButton.setVisibility(View.VISIBLE);
- }
- } else {
- if (mNotificationButtons.getVisibility() == View.VISIBLE) {
- setViewVisibility(mClearButton, View.GONE, R.anim.notification_buttons_out);
- } else {
- mClearButton.setVisibility(View.GONE);
- }
- }
-
/*
mOngoingTitle.setVisibility(ongoing ? View.VISIBLE : View.GONE);
mLatestTitle.setVisibility(latest ? View.VISIBLE : View.GONE);
@@ -759,55 +653,9 @@
}
}
- private class ClockTouchListener implements View.OnTouchListener {
- VelocityTracker mVT = null;
- int mInitX, mInitY;
- public boolean onTouch (View v, MotionEvent event) {
- final int x = (int) event.getX();
- final int y = (int) event.getY();
- switch (event.getAction()) {
- case MotionEvent.ACTION_DOWN:
- mVT = VelocityTracker.obtain();
- mInitX = x;
- mInitY = y;
- mHandler.sendEmptyMessageDelayed(MSG_LIGHTS_OUT,
- ViewConfiguration.getLongPressTimeout());
- break;
- case MotionEvent.ACTION_OUTSIDE:
- case MotionEvent.ACTION_MOVE:
- final Rect r = new Rect();
- final float radius = mSystemInfo.getHeight() / 2;
- if (Math.abs(x - mInitX) > radius || Math.abs(y - mInitY) > radius) {
- mHandler.removeMessages(MSG_LIGHTS_OUT);
- }
- if (mVT == null) break;
- mVT.addMovement(event);
- mVT.computeCurrentVelocity(1000);
- if (mVT.getYVelocity() < -200 && mSystemPanel.getVisibility() == View.GONE) {
- mHandler.removeMessages(MSG_OPEN_SYSTEM_PANEL);
- mHandler.sendEmptyMessage(MSG_OPEN_SYSTEM_PANEL);
- } else if (mVT.getYVelocity() > 200) {
- mHandler.sendEmptyMessage(MSG_LIGHTS_OUT);
- }
- return true;
- case MotionEvent.ACTION_UP:
- case MotionEvent.ACTION_CANCEL:
- mVT.recycle();
- mVT = null;
- mHandler.removeMessages(MSG_LIGHTS_OUT);
- return true;
- }
- return false;
- }
- }
-
private View.OnClickListener mOnClickListener = new View.OnClickListener() {
public void onClick(View v) {
- if (v == mClearButton) {
- onClickClearButton();
- } else if (v == mDoNotDisturbButton) {
- onClickDoNotDisturb();
- } else if (v == mNotificationTrigger) {
+ if (v == mNotificationTrigger) {
onClickNotificationTrigger();
} else if (v == mRecentButton) {
onClickRecentButton();
@@ -815,23 +663,6 @@
}
};
- void onClickClearButton() {
- try {
- mBarService.onClearAllNotifications();
- } catch (RemoteException ex) {
- // system process is dead if we're here.
- }
- animateCollapse();
- refreshNotificationTrigger();
- }
-
- void onClickDoNotDisturb() {
- mNotificationsOn = !mNotificationsOn;
- mIconLayout.setVisibility(mNotificationsOn ? View.VISIBLE : View.INVISIBLE); // TODO: animation
- animateCollapse();
- refreshNotificationTrigger();
- }
-
public void onClickNotificationTrigger() {
if (DEBUG) Slog.d(TAG, "clicked notification icons");
if ((mDisabled & StatusBarManager.DISABLE_EXPAND) == 0) {
@@ -849,17 +680,6 @@
}
}
- public void onClickSystemInfo() {
- if (DEBUG) Slog.d(TAG, "clicked system info");
- if ((mDisabled & StatusBarManager.DISABLE_EXPAND) == 0) {
- int msg = (mSystemPanel.getVisibility() == View.GONE)
- ? MSG_OPEN_SYSTEM_PANEL
- : MSG_CLOSE_SYSTEM_PANEL;
- mHandler.removeMessages(msg);
- mHandler.sendEmptyMessage(msg);
- }
- }
-
public void onClickRecentButton() {
if (DEBUG) Slog.d(TAG, "clicked recent apps");
if (mRecentsPanel == null) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBarView.java
index 15866fe..bd8266a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBarView.java
@@ -40,12 +40,10 @@
public boolean onInterceptTouchEvent(MotionEvent ev) {
if (ev.getAction() == MotionEvent.ACTION_DOWN) {
- mHandler.removeMessages(TabletStatusBarService.MSG_CLOSE_NOTIFICATION_PANEL);
- mHandler.sendEmptyMessage(TabletStatusBarService.MSG_CLOSE_NOTIFICATION_PANEL);
- mHandler.removeMessages(TabletStatusBarService.MSG_CLOSE_SYSTEM_PANEL);
- mHandler.sendEmptyMessage(TabletStatusBarService.MSG_CLOSE_SYSTEM_PANEL);
- mHandler.removeMessages(TabletStatusBarService.MSG_CLOSE_RECENTS_PANEL);
- mHandler.sendEmptyMessage(TabletStatusBarService.MSG_CLOSE_RECENTS_PANEL);
+ mHandler.removeMessages(TabletStatusBar.MSG_CLOSE_NOTIFICATION_PANEL);
+ mHandler.sendEmptyMessage(TabletStatusBar.MSG_CLOSE_NOTIFICATION_PANEL);
+ mHandler.removeMessages(TabletStatusBar.MSG_CLOSE_RECENTS_PANEL);
+ mHandler.sendEmptyMessage(TabletStatusBar.MSG_CLOSE_RECENTS_PANEL);
for (int i=0; i < mPanels.length; i++) {
if (mPanels[i] != null && mPanels[i].getVisibility() == View.VISIBLE) {
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
index 7d58e41..8c857da 100755
--- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
@@ -117,7 +117,6 @@
import android.media.IAudioService;
import android.media.AudioManager;
-import java.io.File;
import java.util.ArrayList;
/**
@@ -2306,12 +2305,8 @@
return getCurrentPortraitRotation(lastRotation);
}
- if (new File("/system/etc/allow_all_orientations").exists()) {
- mOrientationListener.setAllow180Rotation(true);
- } else {
- mOrientationListener.setAllow180Rotation(
- orientation == ActivityInfo.SCREEN_ORIENTATION_FULL_SENSOR);
- }
+ mOrientationListener.setAllow180Rotation(
+ orientation == ActivityInfo.SCREEN_ORIENTATION_FULL_SENSOR);
// case for nosensor meaning ignore sensor and consider only lid
// or orientation sensor disabled
diff --git a/services/java/com/android/server/BackupManagerService.java b/services/java/com/android/server/BackupManagerService.java
index 90ebf3f..6a86076 100644
--- a/services/java/com/android/server/BackupManagerService.java
+++ b/services/java/com/android/server/BackupManagerService.java
@@ -585,6 +585,7 @@
}
}
}
+ tf.close();
} catch (FileNotFoundException fnf) {
// Probably innocuous
Slog.v(TAG, "No ancestral data");
diff --git a/services/java/com/android/server/PackageManagerService.java b/services/java/com/android/server/PackageManagerService.java
index 4707bbf..cd58284 100644
--- a/services/java/com/android/server/PackageManagerService.java
+++ b/services/java/com/android/server/PackageManagerService.java
@@ -7334,6 +7334,7 @@
byte[] data = new byte[avail];
in.read(data);
pw.print(new String(data));
+ in.close();
} catch (FileNotFoundException e) {
} catch (IOException e) {
}
diff --git a/services/sensorservice/SensorService.cpp b/services/sensorservice/SensorService.cpp
index b5e73ac..22a45df 100644
--- a/services/sensorservice/SensorService.cpp
+++ b/services/sensorservice/SensorService.cpp
@@ -464,6 +464,7 @@
}
bool SensorService::SensorEventConnection::addSensor(int32_t handle) {
+ Mutex::Autolock _l(mConnectionLock);
if (mSensorInfo.indexOfKey(handle) <= 0) {
SensorInfo info;
mSensorInfo.add(handle, info);
@@ -473,6 +474,7 @@
}
bool SensorService::SensorEventConnection::removeSensor(int32_t handle) {
+ Mutex::Autolock _l(mConnectionLock);
if (mSensorInfo.removeItem(handle) >= 0) {
return true;
}
@@ -480,16 +482,19 @@
}
bool SensorService::SensorEventConnection::hasSensor(int32_t handle) const {
+ Mutex::Autolock _l(mConnectionLock);
return mSensorInfo.indexOfKey(handle) >= 0;
}
bool SensorService::SensorEventConnection::hasAnySensor() const {
+ Mutex::Autolock _l(mConnectionLock);
return mSensorInfo.size() ? true : false;
}
status_t SensorService::SensorEventConnection::setEventRateLocked(
int handle, nsecs_t ns)
{
+ Mutex::Autolock _l(mConnectionLock);
ssize_t index = mSensorInfo.indexOfKey(handle);
if (index >= 0) {
SensorInfo& info = mSensorInfo.editValueFor(handle);
@@ -506,6 +511,7 @@
// filter out events not for this connection
size_t count = 0;
if (scratch) {
+ Mutex::Autolock _l(mConnectionLock);
size_t i=0;
while (i<numEvents) {
const int32_t curr = buffer[i].sensor;
diff --git a/services/sensorservice/SensorService.h b/services/sensorservice/SensorService.h
index b442779..c0922f5 100644
--- a/services/sensorservice/SensorService.h
+++ b/services/sensorservice/SensorService.h
@@ -75,8 +75,9 @@
sp<SensorService> const mService;
sp<SensorChannel> const mChannel;
+ mutable Mutex mConnectionLock;
- // protected by SensorService::mLock
+ // protected mConnectionLock
struct SensorInfo {
SensorInfo() : ns(DEFAULT_EVENTS_PERIOD) { }
nsecs_t ns;