diff options
-rw-r--r-- | core/java/com/android/internal/util/cm/QSConstants.java | 1 | ||||
-rw-r--r-- | core/java/com/android/internal/util/cm/QSUtils.java | 6 | ||||
-rw-r--r-- | packages/SystemUI/AndroidManifest.xml | 1 | ||||
-rw-r--r-- | packages/SystemUI/res/drawable-hdpi/ic_qs_camera.png | bin | 0 -> 3418 bytes | |||
-rw-r--r-- | packages/SystemUI/res/drawable-mdpi/ic_qs_camera.png | bin | 0 -> 3214 bytes | |||
-rw-r--r-- | packages/SystemUI/res/drawable-xhdpi/ic_qs_camera.png | bin | 0 -> 3575 bytes | |||
-rw-r--r-- | packages/SystemUI/res/layout/quick_settings_tile_camera.xml | 42 | ||||
-rw-r--r-- | packages/SystemUI/res/values/cm_strings.xml | 4 | ||||
-rw-r--r-- | packages/SystemUI/src/com/android/systemui/quicksettings/CameraTile.java | 499 | ||||
-rw-r--r-- | packages/SystemUI/src/com/android/systemui/quicksettings/QuickSettingsTile.java | 17 | ||||
-rw-r--r-- | packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettingsController.java | 30 |
11 files changed, 578 insertions, 22 deletions
diff --git a/core/java/com/android/internal/util/cm/QSConstants.java b/core/java/com/android/internal/util/cm/QSConstants.java index 0e49e39..044d5f9 100644 --- a/core/java/com/android/internal/util/cm/QSConstants.java +++ b/core/java/com/android/internal/util/cm/QSConstants.java @@ -29,6 +29,7 @@ public class QSConstants { public static final String TILE_QUIETHOURS = "toggleQuietHours"; public static final String TILE_VOLUME = "toggleVolume"; public static final String TILE_EXPANDEDDESKTOP = "toggleExpandedDesktop"; + public static final String TILE_CAMERA = "toggleCamera"; public static final String TILE_DELIMITER = "|"; public static ArrayList<String> TILES_DEFAULT = new ArrayList<String>(); diff --git a/core/java/com/android/internal/util/cm/QSUtils.java b/core/java/com/android/internal/util/cm/QSUtils.java index 3da9a7c..39743a9 100644 --- a/core/java/com/android/internal/util/cm/QSUtils.java +++ b/core/java/com/android/internal/util/cm/QSUtils.java @@ -3,8 +3,8 @@ package com.android.internal.util.cm; import android.bluetooth.BluetoothAdapter; import android.content.ContentResolver; import android.content.Context; -import android.content.pm.PackageManager; import android.content.res.Resources; +import android.hardware.Camera; import android.hardware.display.DisplayManager; import android.hardware.display.WifiDisplayStatus; import android.net.ConnectivityManager; @@ -62,4 +62,8 @@ public class QSUtils { Resources res = ctx.getResources(); return res.getBoolean(com.android.internal.R.bool.config_hasDockBattery); } + + public static boolean deviceSupportsCamera() { + return Camera.getNumberOfCameras() > 0; + } } diff --git a/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml index 80bb24d..57d31a1 100644 --- a/packages/SystemUI/AndroidManifest.xml +++ b/packages/SystemUI/AndroidManifest.xml @@ -45,6 +45,7 @@ <uses-permission android:name="android.permission.UPDATE_DEVICE_STATS" /> <uses-permission android:name="android.permission.MASTER_CLEAR" /> <uses-permission android:name="android.permission.VIBRATE" /> + <uses-permission android:name="android.permission.CAMERA" /> <!-- ActivityManager --> <uses-permission android:name="android.permission.GET_TASKS" /> diff --git a/packages/SystemUI/res/drawable-hdpi/ic_qs_camera.png b/packages/SystemUI/res/drawable-hdpi/ic_qs_camera.png Binary files differnew file mode 100644 index 0000000..e0157f7 --- /dev/null +++ b/packages/SystemUI/res/drawable-hdpi/ic_qs_camera.png diff --git a/packages/SystemUI/res/drawable-mdpi/ic_qs_camera.png b/packages/SystemUI/res/drawable-mdpi/ic_qs_camera.png Binary files differnew file mode 100644 index 0000000..17a2e9d --- /dev/null +++ b/packages/SystemUI/res/drawable-mdpi/ic_qs_camera.png diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_qs_camera.png b/packages/SystemUI/res/drawable-xhdpi/ic_qs_camera.png Binary files differnew file mode 100644 index 0000000..8a9b3a3 --- /dev/null +++ b/packages/SystemUI/res/drawable-xhdpi/ic_qs_camera.png diff --git a/packages/SystemUI/res/layout/quick_settings_tile_camera.xml b/packages/SystemUI/res/layout/quick_settings_tile_camera.xml new file mode 100644 index 0000000..12cfebd --- /dev/null +++ b/packages/SystemUI/res/layout/quick_settings_tile_camera.xml @@ -0,0 +1,42 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2013 The CyanogenMod 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. +--> + +<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="match_parent" + android:layout_height="match_parent"> + + <TextView android:id="@+id/camera_text" + style="@style/TextAppearance.QuickSettings.TileView" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:gravity="center" + android:layout_centerInParent="true" + android:drawableTop="@drawable/ic_qs_camera" + android:text="@string/quick_settings_camera_label" + android:singleLine="true" /> + + <FrameLayout android:id="@+id/camera_surface_holder" + android:layout_width="match_parent" + android:layout_height="match_parent"> + + <ImageView android:id="@+id/camera_surface_flash_overlay" + android:src="#88ffffff" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:visibility="gone" /> + + </FrameLayout> +</RelativeLayout> diff --git a/packages/SystemUI/res/values/cm_strings.xml b/packages/SystemUI/res/values/cm_strings.xml index 5aff21f..d0a4362 100644 --- a/packages/SystemUI/res/values/cm_strings.xml +++ b/packages/SystemUI/res/values/cm_strings.xml @@ -65,11 +65,15 @@ <string name="quick_settings_lte">LTE</string> <string name="quick_settings_lte_off">LTE off</string> <string name="quick_settings_volume">Volume</string> + <string name="quick_settings_camera_label">Camera</string> <!-- Expanded desktop strings break the rules a bit - the icon identifies the feature, the string indicates current state --> <string name="quick_settings_expanded_desktop">Expanded</string> <string name="quick_settings_expanded_desktop_off">Normal</string> + <!-- Camera tile toasts --> + <string name="quick_settings_camera_error_connect">Can\'t connect to camera</string> + <!-- Text to display next to the minimal graphical battery meter. [CHAR LIMIT=3] --> <string name="status_bar_settings_battery_meter_min_format" translatable="false"> <xliff:g id="number">%d</xliff:g> diff --git a/packages/SystemUI/src/com/android/systemui/quicksettings/CameraTile.java b/packages/SystemUI/src/com/android/systemui/quicksettings/CameraTile.java new file mode 100644 index 0000000..02114b8 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/quicksettings/CameraTile.java @@ -0,0 +1,499 @@ +package com.android.systemui.quicksettings; + +import android.content.ContentResolver; +import android.content.ContentValues; +import android.content.Context; +import android.content.Intent; +import android.content.pm.PackageManager; +import android.content.res.Resources; +import android.graphics.Rect; +import android.hardware.Camera; +import android.media.ExifInterface; +import android.net.Uri; +import android.os.Environment; +import android.os.Handler; +import android.provider.MediaStore; +import android.provider.MediaStore.Images; +import android.provider.MediaStore.Images.ImageColumns; +import android.provider.MediaStore.MediaColumns; +import android.provider.Settings; +import android.util.Log; +import android.view.LayoutInflater; +import android.view.MotionEvent; +import android.view.OrientationEventListener; +import android.view.Surface; +import android.view.SurfaceHolder; +import android.view.SurfaceView; +import android.view.View; +import android.view.ViewParent; +import android.view.WindowManager; +import android.widget.FrameLayout; +import android.widget.TextView; +import android.widget.Toast; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.List; + +import com.android.systemui.R; +import com.android.systemui.statusbar.phone.PanelView; +import com.android.systemui.statusbar.phone.QuickSettingsContainerView; +import com.android.systemui.statusbar.phone.QuickSettingsController; + +public class CameraTile extends QuickSettingsTile { + private static final String DEFAULT_IMAGE_FILE_NAME_FORMAT = "'IMG'_yyyyMMdd_HHmmss"; + private static final int CAMERA_ID = 0; + + private Handler mHandler; + private TextView mTextView; + private FrameLayout mSurfaceLayout; + private SurfaceView mSurfaceView; + private View mFlashView; + + private Camera mCamera; + private CameraOrientationListener mCameraOrientationListener = null; + private int mOrientation; + private int mJpegRotation; + private int mDisplayRotation; + private Camera.Size mCameraSize; + private boolean mCameraStarted; + private boolean mCameraBusy; + + private Camera.CameraInfo mCameraInfo = new Camera.CameraInfo(); + private Camera.Parameters mParams; + + private Storage mStorage = new Storage(); + private SimpleDateFormat mImageNameFormatter; + + private Runnable mStartRunnable = new Runnable() { + @Override + public void run() { + if (mCamera != null) { + return; + } + + Camera.getCameraInfo(CAMERA_ID, mCameraInfo); + + try { + mCamera = Camera.open(CAMERA_ID); + } catch (Exception e) { + Toast.makeText(mContext, R.string.quick_settings_camera_error_connect, + Toast.LENGTH_SHORT).show(); + return; + } + + // Orientation listener to rotate the camera preview + if (mCameraOrientationListener == null) { + mCameraOrientationListener = new CameraOrientationListener(mContext); + } + mCameraOrientationListener.enable(); + + mParams = mCamera.getParameters(); + + // Use smallest preview size that is bigger than the tile view + Camera.Size previewSize = mParams.getPreviewSize(); + for (Camera.Size size : mParams.getSupportedPreviewSizes()) { + if ((size.width > mTile.getWidth() && size.height > mTile.getHeight()) && + (size.width < previewSize.width && size.height < previewSize.height)) { + previewSize = size; + } + } + mParams.setPreviewSize(previewSize.width, previewSize.height); + + // Use largest picture size + Camera.Size pictureSize = mParams.getPictureSize(); + for (Camera.Size size : mParams.getSupportedPictureSizes()) { + if (size.width > pictureSize.width && size.height > pictureSize.height) { + pictureSize = size; + } + } + mCameraSize = pictureSize; + mParams.setPictureSize(pictureSize.width, pictureSize.height); + + // Try focus with continuous modes first, then basic autofocus + List<String> focusModes = mParams.getSupportedFocusModes(); + if (focusModes.contains(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE)) { + mParams.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE); + } else if (focusModes.contains(Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO)) { + mParams.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO); + } else if (mParams.getSupportedFocusModes().contains(Camera.Parameters.FOCUS_MODE_AUTO)) { + mParams.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO); + } + + mCamera.setParameters(mParams); + updateOrientation(); + + mHandler.postDelayed(new Runnable() { + @Override + public void run() { + final PanelView panel = getContainingPanel(); + if (panel != null && panel.isFullyExpanded()) { + mHandler.postDelayed(this, 100); + } else { + mHandler.post(mReleaseCameraRunnable); + } + } + }, 100); + + mTextView.setVisibility(View.GONE); + mSurfaceView = new CameraPreview(mContext, mCamera); + mSurfaceView.setVisibility(View.VISIBLE); + mSurfaceLayout.addView(mSurfaceView, 0); + } + }; + + private Runnable mTakePictureRunnable = new Runnable() { + @Override + public void run() { + if (mCamera == null) { + return; + } + + // Repeat until the preview has started and we can + // take picture + if (!mCameraStarted) { + mHandler.postDelayed(this, 200); + return; + } + + // To avoid crashes don't post new picture requests + // if previous request has not returned + if (mCameraBusy) { + return; + } + mCameraBusy = true; + + // Display flash animation above the preview + mFlashView.setVisibility(View.VISIBLE); + mFlashView.animate().alpha(0f).withEndAction(new Runnable() { + @Override + public void run() { + mFlashView.setVisibility(View.GONE); + mFlashView.setAlpha(1f); + } + }); + + // Update the JPEG rotation\ + if (mCameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) { + mJpegRotation = (mCameraInfo.orientation - mOrientation + 360) % 360; + } else { + mJpegRotation = (mCameraInfo.orientation + mOrientation) % 360; + } + + mParams.setRotation(mJpegRotation); + mCamera.setParameters(mParams); + + // Request a picture + try { + mCamera.takePicture(null, null, new Camera.PictureCallback() { + @Override + public void onPictureTaken(byte[] data, Camera camera) { + mCameraBusy = false; + + long time = System.currentTimeMillis(); + + int orientation = (mOrientation + mDisplayRotation) % 360; + + mStorage.addImage(mContext.getContentResolver(), + mImageNameFormatter.format(new Date(time)), + time, orientation, data, mCameraSize.width, + mCameraSize.height); + + mCamera.startPreview(); + } + }); + } catch (RuntimeException e) { + // This can happen if user is pressing the + // tile too fast, nothing we can do + } + } + }; + + private Runnable mReleaseCameraRunnable = new Runnable() { + @Override + public void run() { + if (mCamera == null) { + return; + } + + mCamera.stopPreview(); + mCamera.release(); + mCamera = null; + mCameraStarted = false; + mCameraOrientationListener.disable(); + + mTextView.setVisibility(View.VISIBLE); + mSurfaceView.setVisibility(View.GONE); + mSurfaceLayout.removeView(mSurfaceView); + mSurfaceView = null; + } + }; + + private Runnable mAutoFocusRunnable = new Runnable() { + @Override + public void run() { + if (mCameraStarted) { + mCamera.autoFocus(null); + } + } + }; + + public CameraTile(Context context, QuickSettingsController qsc, Handler handler) { + super(context, qsc, R.layout.quick_settings_tile_camera); + mHandler = handler; + + String imageFileNameFormat = DEFAULT_IMAGE_FILE_NAME_FORMAT; + try { + final Resources camRes = context.getPackageManager() + .getResourcesForApplication("com.android.gallery3d"); + int imageFileNameFormatResId = camRes.getIdentifier( + "image_file_name_format", "string", "com.android.gallery3d"); + imageFileNameFormat = camRes.getString(imageFileNameFormatResId); + } catch (PackageManager.NameNotFoundException ex) { + // Use default + } catch (Resources.NotFoundException ex) { + // Use default + } + mImageNameFormatter = new SimpleDateFormat(imageFileNameFormat); + + } + + @Override + void onPostCreate() { + mOnLongClick = new View.OnLongClickListener() { + @Override + public boolean onLongClick(View v) { + if (mCamera != null) { + return false; + } + + Intent intent = new Intent(MediaStore.INTENT_ACTION_STILL_IMAGE_CAMERA); + startSettingsActivity(intent); + return true; + } + }; + + mTextView = (TextView) mTile.findViewById(R.id.camera_text); + mSurfaceLayout = (FrameLayout) mTile.findViewById(R.id.camera_surface_holder); + mFlashView = mTile.findViewById(R.id.camera_surface_flash_overlay); + + super.onPostCreate(); + } + + @Override + public void onClick(View v) { + if (mCamera == null) { + mHandler.post(mStartRunnable); + } else { + mHandler.post(mTakePictureRunnable); + } + } + + private PanelView getContainingPanel() { + ViewParent parent = mContainer; + while (parent != null) { + if (parent instanceof PanelView) { + return (PanelView) parent; + } + parent = parent.getParent(); + } + return null; + } + + private void updateOrientation() { + final WindowManager wm = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE); + int rotation = wm.getDefaultDisplay().getRotation(); + + switch (rotation) { + case Surface.ROTATION_0: + default: + mDisplayRotation = 0; + break; + case Surface.ROTATION_90: + mDisplayRotation = 90; + break; + case Surface.ROTATION_180: + mDisplayRotation = 180; + break; + case Surface.ROTATION_270: + mDisplayRotation = 270; + break; + } + + int cameraOrientation; + + if (mCameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) { + cameraOrientation = (mCameraInfo.orientation + mDisplayRotation) % 360; + cameraOrientation = (360 - cameraOrientation) % 360; // compensate the mirror + } else { + cameraOrientation = (mCameraInfo.orientation - mDisplayRotation + 360) % 360; + } + + mCamera.setDisplayOrientation(cameraOrientation); + } + + private class CameraOrientationListener extends OrientationEventListener { + public CameraOrientationListener(Context context) { + super(context); + } + + @Override + public void onOrientationChanged(int orientation) { + if (mCamera == null || orientation == ORIENTATION_UNKNOWN) { + return; + } + + mOrientation = (orientation + 45) / 90 * 90; + updateOrientation(); + } + } + + private class CameraPreview extends SurfaceView implements SurfaceHolder.Callback { + private SurfaceHolder mHolder; + private Camera mCamera; + + public CameraPreview(Context context, Camera camera) { + super(context); + mCamera = camera; + + // Install a SurfaceHolder.Callback so we get notified when the + // underlying surface is created and destroyed. + mHolder = getHolder(); + mHolder.addCallback(this); + } + + public void surfaceCreated(SurfaceHolder holder) { + // The Surface has been created, now tell the camera where + // to draw the preview. + try { + mCamera.setPreviewDisplay(holder); + mCamera.startPreview(); + mCameraStarted = true; + mCameraBusy = false; + mHandler.postDelayed(mAutoFocusRunnable, 200); + } catch (IOException e) { + // Try release camera + mCamera.release(); + } + } + + public void surfaceDestroyed(SurfaceHolder holder) { + } + + public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) { + } + } + + private class Storage { + private static final String TAG = "CameraStorage"; + private String mRoot = Environment.getExternalStorageDirectory().toString(); + private Storage() {} + + public String writeFile(String title, byte[] data) { + String path = generateFilepath(title); + FileOutputStream out = null; + + try { + out = new FileOutputStream(path); + out.write(data); + } catch (Exception e) { + Log.e(TAG, "Failed to write data", e); + } finally { + try { + out.close(); + } catch (Exception e) { + // Do nothing here + } + } + return path; + } + + // Save the image and add it to media store. + public Uri addImage(ContentResolver resolver, String title, long date, + int orientation, byte[] jpeg, int width, int height) { + // Save the image. + String path = writeFile(title, jpeg); + return addImage(resolver, title, date, orientation, jpeg.length, + path, width, height); + } + + // Add the image to media store. + public Uri addImage(ContentResolver resolver, String title, long date, + int orientation, int jpegLength, String path, int width, int height) { + + try { + ExifInterface exif = new ExifInterface(path); + switch (exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, -1)) { + case ExifInterface.ORIENTATION_ROTATE_90: + orientation = 90; + break; + case ExifInterface.ORIENTATION_ROTATE_180: + orientation = 180; + break; + case ExifInterface.ORIENTATION_ROTATE_270: + orientation = 270; + break; + } + } catch (Exception e) { + Log.w(TAG, "Failed to read exif", e); + } + + if ((mJpegRotation + orientation) % 180 != 0) { + int temp = width; + width = height; + height = width; + } + + // Insert into MediaStore. + ContentValues values = new ContentValues(9); + values.put(ImageColumns.TITLE, title); + values.put(ImageColumns.DISPLAY_NAME, title + ".jpg"); + values.put(ImageColumns.DATE_TAKEN, date); + values.put(ImageColumns.MIME_TYPE, "image/jpeg"); + + // Clockwise rotation in degrees. 0, 90, 180, or 270. + values.put(ImageColumns.ORIENTATION, orientation); + values.put(ImageColumns.DATA, path); + values.put(ImageColumns.SIZE, jpegLength); + values.put(MediaColumns.WIDTH, width); + values.put(MediaColumns.HEIGHT, height); + + Uri uri = null; + + try { + uri = resolver.insert(Images.Media.EXTERNAL_CONTENT_URI, values); + } catch (Throwable th) { + // This can happen when the external volume is already mounted, but + // MediaScanner has not notify MediaProvider to add that volume. + // The picture is still safe and MediaScanner will find it and + // insert it into MediaProvider. The only problem is that the user + // cannot click the thumbnail to review the picture. + Log.e(TAG, "Failed to write MediaStore" + th); + } + return uri; + } + + private String generateDCIM() { + return new File(mRoot, Environment.DIRECTORY_DCIM).toString(); + } + + public String generateDirectory() { + return generateDCIM() + "/Camera"; + } + + private String generateFilepath(String title) { + return generateDirectory() + '/' + title + ".jpg"; + } + + public String generateBucketId() { + return String.valueOf(generateDirectory().toLowerCase().hashCode()); + } + + public int generateBucketIdInt() { + return generateDirectory().toLowerCase().hashCode(); + } + } +} diff --git a/packages/SystemUI/src/com/android/systemui/quicksettings/QuickSettingsTile.java b/packages/SystemUI/src/com/android/systemui/quicksettings/QuickSettingsTile.java index 747e301..48828d0 100644 --- a/packages/SystemUI/src/com/android/systemui/quicksettings/QuickSettingsTile.java +++ b/packages/SystemUI/src/com/android/systemui/quicksettings/QuickSettingsTile.java @@ -24,6 +24,7 @@ import com.android.systemui.statusbar.phone.QuickSettingsTileView; public class QuickSettingsTile implements OnClickListener { protected final Context mContext; + protected QuickSettingsContainerView mContainer; protected QuickSettingsTileView mTile; protected OnClickListener mOnClick; protected OnLongClickListener mOnLongClick; @@ -50,7 +51,8 @@ public class QuickSettingsTile implements OnClickListener { public void setupQuickSettingsTile(LayoutInflater inflater, QuickSettingsContainerView container) { mTile = (QuickSettingsTileView) inflater.inflate(R.layout.quick_settings_tile, container, false); mTile.setContent(mTileLayout, inflater); - container.addView(mTile); + mContainer = container; + mContainer.addView(mTile); onPostCreate(); updateQuickSettings(); mTile.setOnClickListener(this); @@ -73,8 +75,10 @@ public class QuickSettingsTile implements OnClickListener { void updateQuickSettings(){ TextView tv = (TextView) mTile.findViewById(R.id.tile_textview); - tv.setCompoundDrawablesWithIntrinsicBounds(0, mDrawable, 0, 0); - tv.setText(mLabel); + if (tv != null) { + tv.setCompoundDrawablesWithIntrinsicBounds(0, mDrawable, 0, 0); + tv.setText(mLabel); + } } void startSettingsActivity(String action) { @@ -99,8 +103,11 @@ public class QuickSettingsTile implements OnClickListener { } @Override - public final void onClick(View v) { - mOnClick.onClick(v); + public void onClick(View v) { + if (mOnClick != null) { + mOnClick.onClick(v); + } + ContentResolver resolver = mContext.getContentResolver(); boolean shouldCollapse = Settings.System.getIntForUser(resolver, Settings.System.QS_COLLAPSE_PANEL, 0, UserHandle.USER_CURRENT) == 1; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettingsController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettingsController.java index 6541424..568d73d 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettingsController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettingsController.java @@ -22,6 +22,7 @@ import static com.android.internal.util.cm.QSConstants.TILE_AUTOROTATE; import static com.android.internal.util.cm.QSConstants.TILE_BATTERY; import static com.android.internal.util.cm.QSConstants.TILE_BLUETOOTH; import static com.android.internal.util.cm.QSConstants.TILE_BRIGHTNESS; +import static com.android.internal.util.cm.QSConstants.TILE_CAMERA; import static com.android.internal.util.cm.QSConstants.TILE_DELIMITER; import static com.android.internal.util.cm.QSConstants.TILE_EXPANDEDDESKTOP; import static com.android.internal.util.cm.QSConstants.TILE_GPS; @@ -43,14 +44,6 @@ import static com.android.internal.util.cm.QSConstants.TILE_VOLUME; import static com.android.internal.util.cm.QSConstants.TILE_WIFI; import static com.android.internal.util.cm.QSConstants.TILE_WIFIAP; import static com.android.internal.util.cm.QSConstants.TILE_WIMAX; -import static com.android.internal.util.cm.QSUtils.deviceSupportsBluetooth; -import static com.android.internal.util.cm.QSUtils.deviceSupportsDockBattery; -import static com.android.internal.util.cm.QSUtils.deviceSupportsImeSwitcher; -import static com.android.internal.util.cm.QSUtils.deviceSupportsLte; -import static com.android.internal.util.cm.QSUtils.deviceSupportsMobileData; -import static com.android.internal.util.cm.QSUtils.deviceSupportsUsbTether; -import static com.android.internal.util.cm.QSUtils.expandedDesktopEnabled; -import static com.android.internal.util.cm.QSUtils.systemProfilesEnabled; import android.content.BroadcastReceiver; import android.content.ContentResolver; @@ -67,6 +60,7 @@ import android.text.TextUtils; import android.util.Log; import android.view.LayoutInflater; +import com.android.internal.util.cm.QSUtils; import com.android.systemui.quicksettings.AirplaneModeTile; import com.android.systemui.quicksettings.AlarmTile; import com.android.systemui.quicksettings.AutoRotateTile; @@ -74,6 +68,7 @@ import com.android.systemui.quicksettings.BatteryTile; import com.android.systemui.quicksettings.BluetoothTile; import com.android.systemui.quicksettings.BrightnessTile; import com.android.systemui.quicksettings.BugReportTile; +import com.android.systemui.quicksettings.CameraTile; import com.android.systemui.quicksettings.DockBatteryTile; import com.android.systemui.quicksettings.ExpandedDesktopTile; import com.android.systemui.quicksettings.GPSTile; @@ -153,9 +148,10 @@ public class QuickSettingsController { mIMETile = null; // Filter items not compatible with device - boolean bluetoothSupported = deviceSupportsBluetooth(); - boolean mobileDataSupported = deviceSupportsMobileData(mContext); - boolean lteSupported = deviceSupportsLte(mContext); + boolean cameraSupported = QSUtils.deviceSupportsCamera(); + boolean bluetoothSupported = QSUtils.deviceSupportsBluetooth(); + boolean mobileDataSupported = QSUtils.deviceSupportsMobileData(mContext); + boolean lteSupported = QSUtils.deviceSupportsLte(mContext); if (!bluetoothSupported) { TILES_DEFAULT.remove(TILE_BLUETOOTH); @@ -201,6 +197,8 @@ public class QuickSettingsController { qs = new BluetoothTile(mContext, this, mStatusBarService.mBluetoothController); } else if (tile.equals(TILE_BRIGHTNESS)) { qs = new BrightnessTile(mContext, this, mHandler); + } else if (tile.equals(TILE_CAMERA) && cameraSupported) { + qs = new CameraTile(mContext, this, mHandler); } else if (tile.equals(TILE_RINGER)) { qs = new RingerModeTile(mContext, this); } else if (tile.equals(TILE_SYNC)) { @@ -225,7 +223,7 @@ public class QuickSettingsController { qs = new SleepScreenTile(mContext, this); } else if (tile.equals(TILE_PROFILE)) { mTileStatusUris.add(Settings.System.getUriFor(Settings.System.SYSTEM_PROFILES_ENABLED)); - if (systemProfilesEnabled(resolver)) { + if (QSUtils.systemProfilesEnabled(resolver)) { qs = new ProfileTile(mContext, this); } } else if (tile.equals(TILE_NFC)) { @@ -242,7 +240,7 @@ public class QuickSettingsController { qs = new VolumeTile(mContext, this, mHandler); } else if (tile.equals(TILE_EXPANDEDDESKTOP)) { mTileStatusUris.add(Settings.System.getUriFor(Settings.System.EXPANDED_DESKTOP_STYLE)); - if (expandedDesktopEnabled(resolver)) { + if (QSUtils.expandedDesktopEnabled(resolver)) { qs = new ExpandedDesktopTile(mContext, this, mHandler); } } @@ -283,13 +281,13 @@ public class QuickSettingsController { qs.setupQuickSettingsTile(inflater, mContainerView); mQuickSettingsTiles.add(qs); } - if (deviceSupportsImeSwitcher(mContext) && Settings.System.getIntForUser(resolver, + if (QSUtils.deviceSupportsImeSwitcher(mContext) && Settings.System.getIntForUser(resolver, Settings.System.QS_DYNAMIC_IME, 1, UserHandle.USER_CURRENT) == 1) { mIMETile = new InputMethodTile(mContext, this); mIMETile.setupQuickSettingsTile(inflater, mContainerView); mQuickSettingsTiles.add(mIMETile); } - if (deviceSupportsUsbTether(mContext) && Settings.System.getIntForUser(resolver, + if (QSUtils.deviceSupportsUsbTether(mContext) && Settings.System.getIntForUser(resolver, Settings.System.QS_DYNAMIC_USBTETHER, 1, UserHandle.USER_CURRENT) == 1) { QuickSettingsTile qs = new UsbTetherTile(mContext, this); qs.setupQuickSettingsTile(inflater, mContainerView); @@ -298,7 +296,7 @@ public class QuickSettingsController { } private void loadDockBatteryTile(final ContentResolver resolver, final LayoutInflater inflater) { - if (!deviceSupportsDockBattery(mContext)) { + if (!QSUtils.deviceSupportsDockBattery(mContext)) { return; } if (Settings.System.getIntForUser(resolver, |