1 /*
2  * Copyright (C) 2007 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.gallery3d.app;
18 
19 import android.annotation.TargetApi;
20 import android.app.ActionBar;
21 import android.app.Activity;
22 import android.content.AsyncQueryHandler;
23 import android.content.ContentResolver;
24 import android.content.Intent;
25 import android.content.pm.ActivityInfo;
26 import android.database.Cursor;
27 import android.graphics.Bitmap;
28 import android.graphics.drawable.BitmapDrawable;
29 import android.media.AudioManager;
30 import android.net.Uri;
31 import android.os.Build;
32 import android.os.Bundle;
33 import android.provider.MediaStore;
34 import android.provider.OpenableColumns;
35 import android.view.KeyEvent;
36 import android.view.Menu;
37 import android.view.MenuItem;
38 import android.view.View;
39 import android.view.Window;
40 import android.view.WindowManager;
41 import android.widget.ShareActionProvider;
42 
43 import com.android.gallery3d.R;
44 import com.android.gallery3d.common.ApiHelper;
45 import com.android.gallery3d.common.Utils;
46 
47 /**
48  * This activity plays a video from a specified URI.
49  *
50  * The client of this activity can pass a logo bitmap in the intent (KEY_LOGO_BITMAP)
51  * to set the action bar logo so the playback process looks more seamlessly integrated with
52  * the original activity.
53  */
54 public class MovieActivity extends Activity {
55     @SuppressWarnings("unused")
56     private static final String TAG = "MovieActivity";
57     public static final String KEY_LOGO_BITMAP = "logo-bitmap";
58     public static final String KEY_TREAT_UP_AS_BACK = "treat-up-as-back";
59 
60     private MoviePlayer mPlayer;
61     private boolean mFinishOnCompletion;
62     private Uri mUri;
63     private boolean mTreatUpAsBack;
64 
65     @TargetApi(Build.VERSION_CODES.JELLY_BEAN)
setSystemUiVisibility(View rootView)66     private void setSystemUiVisibility(View rootView) {
67         if (ApiHelper.HAS_VIEW_SYSTEM_UI_FLAG_LAYOUT_STABLE) {
68             rootView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE
69                     | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
70                     | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION);
71         }
72     }
73 
74     @Override
onCreate(Bundle savedInstanceState)75     public void onCreate(Bundle savedInstanceState) {
76         super.onCreate(savedInstanceState);
77 
78         requestWindowFeature(Window.FEATURE_ACTION_BAR);
79         requestWindowFeature(Window.FEATURE_ACTION_BAR_OVERLAY);
80 
81         setContentView(R.layout.movie_view);
82         View rootView = findViewById(R.id.movie_view_root);
83 
84         setSystemUiVisibility(rootView);
85 
86         Intent intent = getIntent();
87         initializeActionBar(intent);
88         mFinishOnCompletion = intent.getBooleanExtra(
89                 MediaStore.EXTRA_FINISH_ON_COMPLETION, true);
90         mTreatUpAsBack = intent.getBooleanExtra(KEY_TREAT_UP_AS_BACK, false);
91         mPlayer = new MoviePlayer(rootView, this, intent.getData(), savedInstanceState,
92                 !mFinishOnCompletion) {
93             @Override
94             public void onCompletion() {
95                 if (mFinishOnCompletion) {
96                     finish();
97                 }
98             }
99         };
100         if (intent.hasExtra(MediaStore.EXTRA_SCREEN_ORIENTATION)) {
101             int orientation = intent.getIntExtra(
102                     MediaStore.EXTRA_SCREEN_ORIENTATION,
103                     ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);
104             if (orientation != getRequestedOrientation()) {
105                 setRequestedOrientation(orientation);
106             }
107         }
108         Window win = getWindow();
109         WindowManager.LayoutParams winParams = win.getAttributes();
110         winParams.buttonBrightness = WindowManager.LayoutParams.BRIGHTNESS_OVERRIDE_OFF;
111         winParams.flags |= WindowManager.LayoutParams.FLAG_FULLSCREEN;
112         win.setAttributes(winParams);
113 
114         // We set the background in the theme to have the launching animation.
115         // But for the performance (and battery), we remove the background here.
116         win.setBackgroundDrawable(null);
117     }
118 
setActionBarLogoFromIntent(Intent intent)119     private void setActionBarLogoFromIntent(Intent intent) {
120         Bitmap logo = intent.getParcelableExtra(KEY_LOGO_BITMAP);
121         if (logo != null) {
122             getActionBar().setLogo(
123                     new BitmapDrawable(getResources(), logo));
124         }
125     }
126 
initializeActionBar(Intent intent)127     private void initializeActionBar(Intent intent) {
128         mUri = intent.getData();
129         final ActionBar actionBar = getActionBar();
130         if (actionBar == null) {
131             return;
132         }
133         setActionBarLogoFromIntent(intent);
134         actionBar.setDisplayOptions(
135                 ActionBar.DISPLAY_HOME_AS_UP,
136                 ActionBar.DISPLAY_HOME_AS_UP);
137 
138         String title = intent.getStringExtra(Intent.EXTRA_TITLE);
139         if (title != null) {
140             actionBar.setTitle(title);
141         } else {
142             // Displays the filename as title, reading the filename from the
143             // interface: {@link android.provider.OpenableColumns#DISPLAY_NAME}.
144             AsyncQueryHandler queryHandler =
145                     new AsyncQueryHandler(getContentResolver()) {
146                 @Override
147                 protected void onQueryComplete(int token, Object cookie,
148                         Cursor cursor) {
149                     try {
150                         if ((cursor != null) && cursor.moveToFirst()) {
151                             String displayName = cursor.getString(0);
152 
153                             // Just show empty title if other apps don't set
154                             // DISPLAY_NAME
155                             actionBar.setTitle((displayName == null) ? "" :
156                                     displayName);
157                         }
158                     } finally {
159                         Utils.closeSilently(cursor);
160                     }
161                 }
162             };
163             queryHandler.startQuery(0, null, mUri,
164                     new String[] {OpenableColumns.DISPLAY_NAME}, null, null,
165                     null);
166         }
167     }
168 
169     @Override
onCreateOptionsMenu(Menu menu)170     public boolean onCreateOptionsMenu(Menu menu) {
171         super.onCreateOptionsMenu(menu);
172         getMenuInflater().inflate(R.menu.movie, menu);
173 
174         // Document says EXTRA_STREAM should be a content: Uri
175         // So, we only share the video if it's "content:".
176         MenuItem shareItem = menu.findItem(R.id.action_share);
177         if (ContentResolver.SCHEME_CONTENT.equals(mUri.getScheme())) {
178             shareItem.setVisible(true);
179             ((ShareActionProvider) shareItem.getActionProvider())
180                     .setShareIntent(createShareIntent());
181         } else {
182             shareItem.setVisible(false);
183         }
184         return true;
185     }
186 
createShareIntent()187     private Intent createShareIntent() {
188         Intent intent = new Intent(Intent.ACTION_SEND);
189         intent.setType("video/*");
190         intent.putExtra(Intent.EXTRA_STREAM, mUri);
191         return intent;
192     }
193 
194     @Override
onOptionsItemSelected(MenuItem item)195     public boolean onOptionsItemSelected(MenuItem item) {
196         int id = item.getItemId();
197         if (id == android.R.id.home) {
198             if (mTreatUpAsBack) {
199                 finish();
200             } else {
201                 startActivity(new Intent(this, GalleryActivity.class));
202                 finish();
203             }
204             return true;
205         } else if (id == R.id.action_share) {
206             startActivity(Intent.createChooser(createShareIntent(),
207                     getString(R.string.share)));
208             return true;
209         }
210         return false;
211     }
212 
213     @Override
onStart()214     public void onStart() {
215         ((AudioManager) getSystemService(AUDIO_SERVICE))
216                 .requestAudioFocus(null, AudioManager.STREAM_MUSIC,
217                 AudioManager.AUDIOFOCUS_GAIN_TRANSIENT);
218         super.onStart();
219     }
220 
221     @Override
onStop()222     protected void onStop() {
223         ((AudioManager) getSystemService(AUDIO_SERVICE))
224                 .abandonAudioFocus(null);
225         super.onStop();
226     }
227 
228     @Override
onPause()229     public void onPause() {
230         mPlayer.onPause();
231         super.onPause();
232     }
233 
234     @Override
onResume()235     public void onResume() {
236         mPlayer.onResume();
237         super.onResume();
238     }
239 
240     @Override
onSaveInstanceState(Bundle outState)241     public void onSaveInstanceState(Bundle outState) {
242         super.onSaveInstanceState(outState);
243         mPlayer.onSaveInstanceState(outState);
244     }
245 
246     @Override
onDestroy()247     public void onDestroy() {
248         mPlayer.onDestroy();
249         super.onDestroy();
250     }
251 
252     @Override
onKeyDown(int keyCode, KeyEvent event)253     public boolean onKeyDown(int keyCode, KeyEvent event) {
254         return mPlayer.onKeyDown(keyCode, event)
255                 || super.onKeyDown(keyCode, event);
256     }
257 
258     @Override
onKeyUp(int keyCode, KeyEvent event)259     public boolean onKeyUp(int keyCode, KeyEvent event) {
260         return mPlayer.onKeyUp(keyCode, event)
261                 || super.onKeyUp(keyCode, event);
262     }
263 }
264