Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit fb063617 authored by Doris Liu's avatar Doris Liu
Browse files

Work in progress - Put preview in TextureView

Fixed gesture recognizing and pie menu.
Fixed camera picker. Exposure setting got fixed with rebasing.
Rebased for new pie menu
Fixed camera mode switch listener

Ongoing: secure album, aspect ratio for video recording on ICS

Change-Id: Iedae80815faf81cb49c791885810c8427034a6d1
parent b1c75f60
Loading
Loading
Loading
Loading
+13 −0
Original line number Diff line number Diff line
@@ -290,6 +290,19 @@
                android:configChanges="keyboardHidden|orientation|screenSize"
                android:theme="@style/Theme.Gallery.Dialog"/>

        <activity android:name="com.android.camera.NewCameraActivity"
                android:taskAffinity="com.android.camera.NewCameraActivity"
                android:theme="@style/Theme.Camera"
                android:label="@string/camera_label"
                android:configChanges="orientation|screenSize|keyboardHidden"
                android:clearTaskOnLaunch="true"
                android:windowSoftInputMode="stateAlwaysHidden|adjustPan">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <activity android:name="com.android.camera.CameraActivity"
                android:taskAffinity="com.android.camera.CameraActivity"
                android:label="@string/camera_label"

res/layout/camera.xml

0 → 100644
+21 −0
Original line number Diff line number Diff line
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2013 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.
-->
<com.android.camera.ui.NewCameraRootView
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/camera_app_root"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >
</com.android.camera.ui.NewCameraRootView>
 No newline at end of file
+44 −0
Original line number Diff line number Diff line
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2013 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.
-->

<!-- This layout is shared by phone and tablet in both landscape and portrait
 orientation. The purpose of having this layout is to eventually not manually
 recreate views when the orientation changes, by migrating the views that do not
 need to be recreated in onConfigurationChanged from old photo_module to this
 layout. -->

<merge xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_gravity="center">
    <TextureView
        android:id="@+id/preview_content"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
    <ViewStub android:id="@+id/face_view_stub"
        android:inflatedId="@+id/face_view"
        android:layout="@layout/face_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:visibility="gone"/>
    <com.android.camera.ui.RenderOverlay
        android:id="@+id/render_overlay"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
    <include layout="@layout/camera_controls"
        android:layout_gravity="center"
        style="@style/CameraControls"/>
</merge>
 No newline at end of file
+53 −0
Original line number Diff line number Diff line
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2013 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.
-->
<!-- This layout is shared by phone and tablet in landscape orientation. -->
<merge xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_height="match_parent"
    android:layout_width="match_parent">
    <TextureView
        android:id="@+id/preview_content"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
    <FrameLayout android:id="@+id/preview_border"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:visibility="gone"
            android:background="@drawable/ic_snapshot_border" />
    <com.android.camera.ui.RenderOverlay
        android:id="@+id/render_overlay"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
    <com.android.camera.ui.RotateLayout android:id="@+id/recording_time_rect"
            style="@style/ViewfinderLabelLayout">
        <include layout="@layout/viewfinder_labels_video" android:id="@+id/labels" />
    </com.android.camera.ui.RotateLayout>
    <ImageView android:id="@+id/review_image"
            android:layout_height="match_parent"
            android:layout_width="match_parent"
            android:visibility="gone"
            android:background="@android:color/black"/>
    <ImageView
            android:id="@+id/btn_play"
            style="@style/ReviewControlIcon"
            android:layout_centerInParent="true"
            android:src="@drawable/ic_gallery_play_big"
            android:visibility="gone"
            android:onClick="onReviewPlayClicked"/>

    <include layout="@layout/camera_controls"
        android:layout_gravity="center"
        style="@style/CameraControls"/>
</merge>
+326 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2013 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.camera;

import android.app.Activity;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.ServiceConnection;
import android.content.pm.ActivityInfo;
import android.content.res.Configuration;
import android.os.Bundle;
import android.os.IBinder;
import android.provider.Settings;
import android.view.MotionEvent;
import android.view.OrientationEventListener;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.view.WindowManager;

import com.android.camera.ui.CameraSwitcher.CameraSwitchListener;
import com.android.camera.ui.NewCameraRootView;
import com.android.gallery3d.R;
import com.android.gallery3d.common.ApiHelper;
import com.android.gallery3d.util.LightCycleHelper;

public class NewCameraActivity extends Activity
    implements CameraSwitchListener {
    public static final int PHOTO_MODULE_INDEX = 0;
    public static final int VIDEO_MODULE_INDEX = 1;
    public static final int PANORAMA_MODULE_INDEX = 2;
    public static final int LIGHTCYCLE_MODULE_INDEX = 3;
    private static final String INTENT_ACTION_STILL_IMAGE_CAMERA_SECURE =
            "android.media.action.STILL_IMAGE_CAMERA_SECURE";
    public static final String ACTION_IMAGE_CAPTURE_SECURE =
            "android.media.action.IMAGE_CAPTURE_SECURE";
    // The intent extra for camera from secure lock screen. True if the gallery
    // should only show newly captured pictures. sSecureAlbumId does not
    // increment. This is used when switching between camera, camcorder, and
    // panorama. If the extra is not set, it is in the normal camera mode.
    public static final String SECURE_CAMERA_EXTRA = "secure_camera";


    private int mCurrentModuleIndex;
    private NewCameraModule mCurrentModule;
    private View mRootView;
    private int mResultCodeForTesting;
    private Intent mResultDataForTesting;
    private OnScreenHint mStorageHint;
    private long mStorageSpace = Storage.LOW_STORAGE_THRESHOLD;
    private PhotoModule mController;
    private boolean mAutoRotateScreen;
    private boolean mSecureCamera;
    private int mLastRawOrientation;
    private MyOrientationEventListener mOrientationListener;
    private class MyOrientationEventListener
        extends OrientationEventListener {
        public MyOrientationEventListener(Context context) {
            super(context);
        }

        @Override
        public void onOrientationChanged(int orientation) {
            // We keep the last known orientation. So if the user first orient
            // the camera then point the camera to floor or sky, we still have
            // the correct orientation.
            if (orientation == ORIENTATION_UNKNOWN) return;
            mLastRawOrientation = orientation;
            mCurrentModule.onOrientationChanged(orientation);
        }
    }
    private MediaSaveService mMediaSaveService;
    private ServiceConnection mConnection = new ServiceConnection() {
            @Override
            public void onServiceConnected(ComponentName className, IBinder b) {
                mMediaSaveService = ((MediaSaveService.LocalBinder) b).getService();
                mCurrentModule.onMediaSaveServiceConnected(mMediaSaveService);
            }
            @Override
            public void onServiceDisconnected(ComponentName className) {
                mMediaSaveService = null;
            }};

    public MediaSaveService getMediaSaveService() {
        return mMediaSaveService;
    }

    private void bindMediaSaveService() {
        Intent intent = new Intent(this, MediaSaveService.class);
        startService(intent);  // start service before binding it so the
                               // service won't be killed if we unbind it.
        bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
    }

    private void unbindMediaSaveService() {
        mMediaSaveService.setListener(null);
        unbindService(mConnection);
    }

    @Override
    public void onCreate(Bundle state) {
        super.onCreate(state);
        setContentView(R.layout.camera);
        if (ApiHelper.HAS_ROTATION_ANIMATION) {
            setRotationAnimation();
        }
        // Check if this is in the secure camera mode.
        Intent intent = getIntent();
        String action = intent.getAction();
        if (INTENT_ACTION_STILL_IMAGE_CAMERA_SECURE.equals(action)) {
            mSecureCamera = true;
            // Use a new album when this is started from the lock screen.
        //TODO:    sSecureAlbumId++;
        } else if (ACTION_IMAGE_CAPTURE_SECURE.equals(action)) {
            mSecureCamera = true;
        } else {
            mSecureCamera = intent.getBooleanExtra(SECURE_CAMERA_EXTRA, false);
        }
        /*TODO: if (mSecureCamera) {
            IntentFilter filter = new IntentFilter(Intent.ACTION_SCREEN_OFF);
            registerReceiver(mScreenOffReceiver, filter);
            if (sScreenOffReceiver == null) {
                sScreenOffReceiver = new ScreenOffReceiver();
                getApplicationContext().registerReceiver(sScreenOffReceiver, filter);
            }
        }*/
        mRootView = findViewById(R.id.camera_app_root);
        mCurrentModule = new NewPhotoModule();
        mCurrentModule.init(this, mRootView);
        mOrientationListener = new MyOrientationEventListener(this);
        bindMediaSaveService();
    }

    private void setRotationAnimation() {
        int rotationAnimation = WindowManager.LayoutParams.ROTATION_ANIMATION_ROTATE;
        rotationAnimation = WindowManager.LayoutParams.ROTATION_ANIMATION_CROSSFADE;
        Window win = getWindow();
        WindowManager.LayoutParams winParams = win.getAttributes();
        winParams.rotationAnimation = rotationAnimation;
        win.setAttributes(winParams);
    }

    @Override
    public void onUserInteraction() {
        super.onUserInteraction();
        mCurrentModule.onUserInteraction();
    }

    @Override
    public void onPause() {
        mOrientationListener.disable();
        mCurrentModule.onPauseBeforeSuper();
        super.onPause();
        mCurrentModule.onPauseAfterSuper();
    }

    @Override
    public void onResume() {
        if (Settings.System.getInt(getContentResolver(),
                Settings.System.ACCELEROMETER_ROTATION, 0) == 0) {// auto-rotate off
            setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);
            mAutoRotateScreen = false;
        } else {
            setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_FULL_SENSOR);
            mAutoRotateScreen = true;
        }
        mOrientationListener.enable();
        mCurrentModule.onResumeBeforeSuper();
        super.onResume();
        mCurrentModule.onResumeAfterSuper();
    }

    @Override
    public void onDestroy() {
        unbindMediaSaveService();
        super.onDestroy();
    }

    @Override
    public void onConfigurationChanged(Configuration config) {
        super.onConfigurationChanged(config);
        mCurrentModule.onConfigurationChanged(config);
    }

    @Override
    public boolean dispatchTouchEvent(MotionEvent m) {
        return mCurrentModule.dispatchTouchEvent(m);
    }
    public boolean isAutoRotateScreen() {
        return mAutoRotateScreen;
    }

    protected void updateStorageSpace() {
        mStorageSpace = Storage.getAvailableSpace();
    }

    protected long getStorageSpace() {
        return mStorageSpace;
    }

    protected void updateStorageSpaceAndHint() {
        updateStorageSpace();
        updateStorageHint(mStorageSpace);
    }

    protected void updateStorageHint() {
        updateStorageHint(mStorageSpace);
    }

    protected boolean updateStorageHintOnResume() {
        return true;
    }

    protected void updateStorageHint(long storageSpace) {
        String message = null;
        if (storageSpace == Storage.UNAVAILABLE) {
            message = getString(R.string.no_storage);
        } else if (storageSpace == Storage.PREPARING) {
            message = getString(R.string.preparing_sd);
        } else if (storageSpace == Storage.UNKNOWN_SIZE) {
            message = getString(R.string.access_sd_fail);
        } else if (storageSpace <= Storage.LOW_STORAGE_THRESHOLD) {
            message = getString(R.string.spaceIsLow_content);
        }

        if (message != null) {
            if (mStorageHint == null) {
                mStorageHint = OnScreenHint.makeText(this, message);
            } else {
                mStorageHint.setText(message);
            }
            mStorageHint.show();
        } else if (mStorageHint != null) {
            mStorageHint.cancel();
            mStorageHint = null;
        }
    }

    protected void setResultEx(int resultCode) {
        mResultCodeForTesting = resultCode;
        setResult(resultCode);
    }

    protected void setResultEx(int resultCode, Intent data) {
        mResultCodeForTesting = resultCode;
        mResultDataForTesting = data;
        setResult(resultCode, data);
    }

    public int getResultCode() {
        return mResultCodeForTesting;
    }

    public Intent getResultData() {
        return mResultDataForTesting;
    }

    public boolean isSecureCamera() {
        return mSecureCamera;
    }

    @Override
    public void onCameraSelected(int i) {
        if (mCurrentModuleIndex == i) return;

        CameraHolder.instance().keep();
        closeModule(mCurrentModule);
        mCurrentModuleIndex = i;
        switch (i) {
            case VIDEO_MODULE_INDEX:
                mCurrentModule = new NewVideoModule();
                break;
            case PHOTO_MODULE_INDEX:
                mCurrentModule = new NewPhotoModule();
                break;
            /* TODO:
            case PANORAMA_MODULE_INDEX:
                mCurrentModule = new PanoramaModule();
                break;
            case LIGHTCYCLE_MODULE_INDEX:
                mCurrentModule = LightCycleHelper.createPanoramaModule();
                break; */
           default:
               break;
        }

        openModule(mCurrentModule);
        mCurrentModule.onOrientationChanged(mLastRawOrientation);
        if (mMediaSaveService != null) {
            mCurrentModule.onMediaSaveServiceConnected(mMediaSaveService);
        }
    }

    private void openModule(NewCameraModule module) {
        module.init(this, mRootView);
        module.onResumeBeforeSuper();
        module.onResumeAfterSuper();
        ((NewCameraRootView) mRootView).cameraModuleChanged();
    }

    private void closeModule(NewCameraModule module) {
        module.onPauseBeforeSuper();
        module.onPauseAfterSuper();
        ((ViewGroup) mRootView).removeAllViews();
    }

    @Override
    public void onShowSwitcherPopup() {
    }
}
 No newline at end of file
Loading