• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2013 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.camera.ui;
18 
19 import android.app.Activity;
20 import android.content.Context;
21 import android.content.Intent;
22 import android.provider.MediaStore;
23 import android.util.AttributeSet;
24 import android.view.MotionEvent;
25 import android.view.View;
26 import android.view.ViewConfiguration;
27 import android.widget.FrameLayout;
28 
29 import com.android.camera.app.CameraAppUI;
30 import com.android.camera.debug.Log;
31 import com.android.camera.util.CameraUtil;
32 import com.android.camera.util.UsageStatistics;
33 import com.android.camera.widget.FilmstripLayout;
34 import com.android.camera2.R;
35 import com.google.common.logging.eventprotos;
36 
37 public class MainActivityLayout extends FrameLayout {
38 
39     private final Log.Tag TAG = new Log.Tag("MainActivityLayout");
40     // Only check for intercepting touch events within first 500ms
41     private static final int SWIPE_TIME_OUT = 500;
42 
43     private ModeListView mModeList;
44     private FilmstripLayout mFilmstripLayout;
45     private boolean mCheckToIntercept;
46     private MotionEvent mDown;
47     private final int mSlop;
48     private boolean mRequestToInterceptTouchEvents = false;
49     private View mTouchReceiver = null;
50     private final boolean mIsCaptureIntent;
51     private CameraAppUI.NonDecorWindowSizeChangedListener mNonDecorWindowSizeChangedListener = null;
52 
53     // TODO: This can be removed once we come up with a new design for b/13751653.
54     @Deprecated
55     private boolean mSwipeEnabled = true;
56 
MainActivityLayout(Context context, AttributeSet attrs)57     public MainActivityLayout(Context context, AttributeSet attrs) {
58         super(context, attrs);
59         mSlop = ViewConfiguration.get(context).getScaledTouchSlop();
60 
61         Activity activity = (Activity) context;
62         Intent intent = activity.getIntent();
63         String action = intent.getAction();
64         mIsCaptureIntent = (MediaStore.ACTION_IMAGE_CAPTURE.equals(action)
65                 || MediaStore.ACTION_IMAGE_CAPTURE_SECURE.equals(action)
66                 || MediaStore.ACTION_VIDEO_CAPTURE.equals(action));
67     }
68 
69     /**
70      * Enables or disables the swipe for modules not supporting the new swipe
71      * logic yet.
72      */
73     @Deprecated
setSwipeEnabled(boolean enabled)74     public void setSwipeEnabled(boolean enabled) {
75         mSwipeEnabled = enabled;
76     }
77 
78     @Override
onInterceptTouchEvent(MotionEvent ev)79     public boolean onInterceptTouchEvent(MotionEvent ev) {
80         if (ev.getActionMasked() == MotionEvent.ACTION_DOWN) {
81             mCheckToIntercept = true;
82             mDown = MotionEvent.obtain(ev);
83             mTouchReceiver = null;
84             mRequestToInterceptTouchEvents = false;
85             return false;
86         } else if (mRequestToInterceptTouchEvents) {
87             mRequestToInterceptTouchEvents = false;
88             onTouchEvent(mDown);
89             return true;
90         } else if (ev.getActionMasked() == MotionEvent.ACTION_POINTER_DOWN) {
91             // Do not intercept touch once child is in zoom mode
92             mCheckToIntercept = false;
93             return false;
94         } else {
95             // TODO: This can be removed once we come up with a new design for b/13751653.
96             if (!mCheckToIntercept) {
97                 return false;
98             }
99             if (ev.getEventTime() - ev.getDownTime() > SWIPE_TIME_OUT) {
100                 return false;
101             }
102             if (mIsCaptureIntent || !mSwipeEnabled) {
103                 return false;
104             }
105             int deltaX = (int) (ev.getX() - mDown.getX());
106             int deltaY = (int) (ev.getY() - mDown.getY());
107             if (ev.getActionMasked() == MotionEvent.ACTION_MOVE
108                     && Math.abs(deltaX) > mSlop) {
109                 // Intercept right swipe
110                 if (deltaX >= Math.abs(deltaY) * 2) {
111                     mTouchReceiver = mModeList;
112                     onTouchEvent(mDown);
113                     return true;
114                 }
115                 // Intercept left swipe
116                 else if (deltaX < -Math.abs(deltaY) * 2) {
117                     mTouchReceiver = mFilmstripLayout;
118                     onTouchEvent(mDown);
119                     return true;
120                 }
121             }
122         }
123         return false;
124     }
125 
126     @Override
onTouchEvent(MotionEvent ev)127     public boolean onTouchEvent(MotionEvent ev) {
128         if (mTouchReceiver != null) {
129             mTouchReceiver.setVisibility(VISIBLE);
130             return mTouchReceiver.dispatchTouchEvent(ev);
131         }
132         return false;
133     }
134 
135     @Override
onFinishInflate()136     public void onFinishInflate() {
137         mModeList = (ModeListView) findViewById(R.id.mode_list_layout);
138         mFilmstripLayout = (FilmstripLayout) findViewById(R.id.filmstrip_layout);
139     }
140 
redirectTouchEventsTo(View touchReceiver)141     public void redirectTouchEventsTo(View touchReceiver) {
142         if (touchReceiver == null) {
143             Log.e(TAG, "Cannot redirect touch to a null receiver.");
144             return;
145         }
146         mTouchReceiver = touchReceiver;
147         mRequestToInterceptTouchEvents = true;
148     }
149 
150     @Override
onMeasure(int widthMeasureSpec, int heightMeasureSpec)151     public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
152         if (mNonDecorWindowSizeChangedListener != null) {
153             mNonDecorWindowSizeChangedListener.onNonDecorWindowSizeChanged(
154                     MeasureSpec.getSize(widthMeasureSpec), MeasureSpec.getSize(heightMeasureSpec),
155                     CameraUtil.getDisplayRotation(getContext()));
156         }
157         super.onMeasure(widthMeasureSpec, heightMeasureSpec);
158     }
159 
160     /**
161      * Sets a listener that gets notified when the layout size is changed. This
162      * size is the size of main activity layout. It is also the size of the window
163      * excluding the system decor such as status bar and nav bar.
164      */
setNonDecorWindowSizeChangedListener( CameraAppUI.NonDecorWindowSizeChangedListener listener)165     public void setNonDecorWindowSizeChangedListener(
166             CameraAppUI.NonDecorWindowSizeChangedListener listener) {
167         mNonDecorWindowSizeChangedListener = listener;
168         if (mNonDecorWindowSizeChangedListener != null) {
169             mNonDecorWindowSizeChangedListener.onNonDecorWindowSizeChanged(
170                     getMeasuredWidth(), getMeasuredHeight(),
171                     CameraUtil.getDisplayRotation(getContext()));
172         }
173     }
174 }