diff --git a/metadata/net.nurik.roman.muzei.txt b/metadata/net.nurik.roman.muzei.txt index eaec35104b..e581cfa552 100644 --- a/metadata/net.nurik.roman.muzei.txt +++ b/metadata/net.nurik.roman.muzei.txt @@ -45,6 +45,13 @@ Build:2.3,23015 gradle=prod rm=wearable,example-watchface +Build:2.3.1,23124 + commit=v2.3.1-rc3 + subdir=main + patch=2.3.1-remove-play-services.patch + gradle=prod + rm=wearable,example-watchface + Maintainer Notes: Custom version format, so no UCM applies. @@ -55,5 +62,5 @@ rest of the code has be cleaned up from FirebaseAnalytics. Auto Update Mode:None Update Check Mode:None -Current Version:2.3 -Current Version Code:23015 +Current Version:2.3.1 +Current Version Code:23124 diff --git a/metadata/net.nurik.roman.muzei/2.3.1-remove-play-services.patch b/metadata/net.nurik.roman.muzei/2.3.1-remove-play-services.patch new file mode 100644 index 0000000000..191d57b55e --- /dev/null +++ b/metadata/net.nurik.roman.muzei/2.3.1-remove-play-services.patch @@ -0,0 +1,548 @@ +diff --git a/build.gradle b/build.gradle +index 33c940f..ee7f343 100644 +--- a/build.gradle ++++ b/build.gradle +@@ -20,7 +20,6 @@ buildscript { + } + dependencies { + classpath 'com.android.tools.build:gradle:2.3.1' +- classpath 'com.google.gms:google-services:3.0.0' + } + } + +diff --git a/main/build.gradle b/main/build.gradle +index 0f5ac90..067f6c6 100644 +--- a/main/build.gradle ++++ b/main/build.gradle +@@ -114,10 +114,6 @@ configurations { + dependencies { + compile "com.squareup.okhttp3:okhttp:$rootProject.ext.okhttpVersion" + compile "com.squareup.picasso:picasso:$rootProject.ext.picassoVersion" +- compile "com.google.android.gms:play-services-wearable:$rootProject.ext.googlePlayServicesVersion" +- compile "com.google.firebase:firebase-core:$rootProject.ext.googlePlayServicesVersion" +- // Only use crash reporting in the "prod" product flavor +- prodCompile "com.google.firebase:firebase-crash:$rootProject.ext.googlePlayServicesVersion" + compile "com.twofortyfouram:android-plugin-api-for-locale:1.0.2" + compile "org.greenrobot:eventbus:3.0.0" + compile "com.android.support:appcompat-v7:$rootProject.ext.supportLibraryVersion" +@@ -131,8 +127,4 @@ dependencies { + compile project(':android-client-common') + compile project(':source-featured-art') + compile project(':source-gallery') +- prodReleaseWearApp project(path: ':wearable', configuration: 'prodRelease') +- prodPublicBetaWearApp project(path: ':wearable', configuration: 'prodPublicBeta') + } +- +-apply plugin: 'com.google.gms.google-services' +\ No newline at end of file +diff --git a/main/src/main/java/com/google/android/apps/muzei/MuzeiActivity.java b/main/src/main/java/com/google/android/apps/muzei/MuzeiActivity.java +index 27e9f20..97fc8ea 100644 +--- a/main/src/main/java/com/google/android/apps/muzei/MuzeiActivity.java ++++ b/main/src/main/java/com/google/android/apps/muzei/MuzeiActivity.java +@@ -75,7 +75,6 @@ import com.google.android.apps.muzei.util.DrawInsetsFrameLayout; + import com.google.android.apps.muzei.util.PanScaleProxyView; + import com.google.android.apps.muzei.util.ScrimUtil; + import com.google.android.apps.muzei.util.TypefaceUtil; +-import com.google.firebase.analytics.FirebaseAnalytics; + + import net.nurik.roman.muzei.BuildConfig; + import net.nurik.roman.muzei.R; +@@ -259,7 +258,6 @@ public class MuzeiActivity extends AppCompatActivity { + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.muzei_activity); +- FirebaseAnalytics.getInstance(this).setUserProperty("device_type", BuildConfig.DEVICE_TYPE); + + mContainerView = (DrawInsetsFrameLayout) findViewById(R.id.container); + +@@ -322,7 +320,6 @@ public class MuzeiActivity extends AppCompatActivity { + findViewById(R.id.activate_muzei_button).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { +- FirebaseAnalytics.getInstance(MuzeiActivity.this).logEvent("activate", null); + try { + startActivity(new Intent(WallpaperManager.ACTION_CHANGE_LIVE_WALLPAPER) + .putExtra(WallpaperManager.EXTRA_LIVE_WALLPAPER_COMPONENT, +@@ -419,7 +416,6 @@ public class MuzeiActivity extends AppCompatActivity { + + // Special work + if (newUiMode == UI_MODE_INTRO) { +- FirebaseAnalytics.getInstance(this).logEvent(FirebaseAnalytics.Event.TUTORIAL_BEGIN, null); + final View activateButton = findViewById(R.id.activate_muzei_button); + activateButton.setAlpha(0); + final AnimatedMuzeiLogoFragment logoFragment = (AnimatedMuzeiLogoFragment) +@@ -516,7 +512,6 @@ public class MuzeiActivity extends AppCompatActivity { + } + + if (newUiMode == UI_MODE_ART_DETAIL) { +- FirebaseAnalytics.getInstance(this).logEvent(FirebaseAnalytics.Event.TUTORIAL_COMPLETE, null); + } + + mPanScaleProxyView.setVisibility(newUiMode == UI_MODE_ART_DETAIL +@@ -694,7 +689,6 @@ public class MuzeiActivity extends AppCompatActivity { + + switch (menuItem.getItemId()) { + case R.id.action_settings: +- FirebaseAnalytics.getInstance(MuzeiActivity.this).logEvent("settings_open", null); + startActivity(new Intent(MuzeiActivity.this, SettingsActivity.class)); + return true; + } +diff --git a/main/src/main/java/com/google/android/apps/muzei/MuzeiWallpaperService.java b/main/src/main/java/com/google/android/apps/muzei/MuzeiWallpaperService.java +index 986366c..754e2fe 100644 +--- a/main/src/main/java/com/google/android/apps/muzei/MuzeiWallpaperService.java ++++ b/main/src/main/java/com/google/android/apps/muzei/MuzeiWallpaperService.java +@@ -47,8 +47,6 @@ import com.google.android.apps.muzei.render.RenderController; + import com.google.android.apps.muzei.settings.Prefs; + import com.google.android.apps.muzei.shortcuts.ArtworkInfoShortcutController; + import com.google.android.apps.muzei.sync.TaskQueueService; +-import com.google.android.apps.muzei.wearable.WearableController; +-import com.google.firebase.analytics.FirebaseAnalytics; + + import net.nurik.roman.muzei.BuildConfig; + import net.rbgrn.android.glwallpaperservice.GLWallpaperService; +@@ -62,8 +60,6 @@ public class MuzeiWallpaperService extends GLWallpaperService { + private NetworkChangeReceiver mNetworkChangeReceiver; + private HandlerThread mNotificationHandlerThread; + private ContentObserver mNotificationContentObserver; +- private HandlerThread mWearableHandlerThread; +- private ContentObserver mWearableContentObserver; + private HandlerThread mArtworkInfoShortcutHandlerThread; + private ContentObserver mArtworkInfoShortcutContentObserver; + +@@ -91,7 +87,6 @@ public class MuzeiWallpaperService extends GLWallpaperService { + } + + private void initialize() { +- FirebaseAnalytics.getInstance(this).setUserProperty("device_type", BuildConfig.DEVICE_TYPE); + SourceManager.subscribeToSelectedSource(MuzeiWallpaperService.this); + mNetworkChangeReceiver = new NetworkChangeReceiver(); + IntentFilter networkChangeFilter = new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION); +@@ -116,18 +111,6 @@ public class MuzeiWallpaperService extends GLWallpaperService { + getContentResolver().registerContentObserver(MuzeiContract.Artwork.CONTENT_URI, + true, mNotificationContentObserver); + +- // Set up a thread to update Android Wear whenever the artwork changes +- mWearableHandlerThread = new HandlerThread("MuzeiWallpaperService-Wearable"); +- mWearableHandlerThread.start(); +- mWearableContentObserver = new ContentObserver(new Handler(mWearableHandlerThread.getLooper())) { +- @Override +- public void onChange(final boolean selfChange, final Uri uri) { +- WearableController.updateArtwork(MuzeiWallpaperService.this); +- } +- }; +- getContentResolver().registerContentObserver(MuzeiContract.Artwork.CONTENT_URI, +- true, mWearableContentObserver); +- + // Set up a thread to update the Artwork Info shortcut whenever the artwork changes + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N_MR1) { + mArtworkInfoShortcutHandlerThread = new HandlerThread("MuzeiWallpaperService-ArtworkInfoShortcut"); +@@ -154,8 +137,6 @@ public class MuzeiWallpaperService extends GLWallpaperService { + getContentResolver().unregisterContentObserver(mArtworkInfoShortcutContentObserver); + mArtworkInfoShortcutHandlerThread.quitSafely(); + } +- getContentResolver().unregisterContentObserver(mWearableContentObserver); +- mWearableHandlerThread.quitSafely(); + getContentResolver().unregisterContentObserver(mNotificationContentObserver); + mNotificationHandlerThread.quitSafely(); + if (mNetworkChangeReceiver != null) { +@@ -273,7 +254,6 @@ public class MuzeiWallpaperService extends GLWallpaperService { + + private void activateWallpaper() { + mWallpaperActivated = true; +- FirebaseAnalytics.getInstance(MuzeiWallpaperService.this).logEvent("wallpaper_created", null); + EventBus.getDefault().postSticky(new WallpaperActiveStateChangedEvent(true)); + } + +@@ -290,7 +270,6 @@ public class MuzeiWallpaperService extends GLWallpaperService { + public void onDestroy() { + EventBus.getDefault().unregister(this); + if (mWallpaperActivated) { +- FirebaseAnalytics.getInstance(MuzeiWallpaperService.this).logEvent("wallpaper_destroyed", null); + EventBus.getDefault().postSticky(new WallpaperActiveStateChangedEvent(false)); + } else if (!isPreview()) { + unregisterReceiver(mEngineUnlockReceiver); +diff --git a/main/src/main/java/com/google/android/apps/muzei/PhotoSetAsTargetActivity.java b/main/src/main/java/com/google/android/apps/muzei/PhotoSetAsTargetActivity.java +index 928a386..c1905a2 100644 +--- a/main/src/main/java/com/google/android/apps/muzei/PhotoSetAsTargetActivity.java ++++ b/main/src/main/java/com/google/android/apps/muzei/PhotoSetAsTargetActivity.java +@@ -25,7 +25,6 @@ import android.os.Bundle; + + import com.google.android.apps.muzei.gallery.GalleryArtSource; + import com.google.android.apps.muzei.gallery.GalleryContract; +-import com.google.firebase.analytics.FirebaseAnalytics; + + public class PhotoSetAsTargetActivity extends Activity { + @Override +@@ -39,11 +38,6 @@ public class PhotoSetAsTargetActivity extends Activity { + Uri photoUri = getIntent().getData(); + + // Select the gallery source +- Bundle bundle = new Bundle(); +- bundle.putString(FirebaseAnalytics.Param.ITEM_ID, +- new ComponentName(this, GalleryArtSource.class).flattenToShortString()); +- bundle.putString(FirebaseAnalytics.Param.CONTENT_TYPE, "sources"); +- FirebaseAnalytics.getInstance(this).logEvent(FirebaseAnalytics.Event.SELECT_CONTENT, bundle); + SourceManager.selectSource(this, new ComponentName(this, GalleryArtSource.class)); + + // Add and publish the chosen photo +diff --git a/main/src/main/java/com/google/android/apps/muzei/SourceManager.java b/main/src/main/java/com/google/android/apps/muzei/SourceManager.java +index 7f8289b..ed5e225 100644 +--- a/main/src/main/java/com/google/android/apps/muzei/SourceManager.java ++++ b/main/src/main/java/com/google/android/apps/muzei/SourceManager.java +@@ -33,7 +33,6 @@ import com.google.android.apps.muzei.api.MuzeiContract; + import com.google.android.apps.muzei.api.UserCommand; + import com.google.android.apps.muzei.featuredart.FeaturedArtSource; + import com.google.android.apps.muzei.sync.TaskQueueService; +-import com.google.firebase.analytics.FirebaseAnalytics; + + import net.nurik.roman.muzei.BuildConfig; + +@@ -117,7 +116,6 @@ public class SourceManager { + try { + context.getContentResolver().applyBatch(MuzeiContract.AUTHORITY, operations); + sharedPrefs.edit().remove(PREF_SELECTED_SOURCE).remove(PREF_SOURCE_STATES).apply(); +- sendSelectedSourceAnalytics(context, selectedSource); + } catch (RemoteException | OperationApplicationException e) { + Log.e(TAG, "Error writing sources to ContentProvider", e); + } +@@ -163,7 +161,6 @@ public class SourceManager { + + try { + context.getContentResolver().applyBatch(MuzeiContract.AUTHORITY, operations); +- sendSelectedSourceAnalytics(context, source); + } catch (RemoteException | OperationApplicationException e) { + Log.e(TAG, "Error writing sources to ContentProvider", e); + } +@@ -174,24 +171,6 @@ public class SourceManager { + context.startService(TaskQueueService.getDownloadCurrentArtworkIntent(context)); + } + +- private static void sendSelectedSourceAnalytics(Context context, ComponentName selectedSource) { +- // The current limit for user property values +- final int MAX_VALUE_LENGTH = 36; +- String packageName = selectedSource.getPackageName(); +- if (packageName.length() > MAX_VALUE_LENGTH) { +- packageName = packageName.substring(packageName.length() - MAX_VALUE_LENGTH); +- } +- FirebaseAnalytics.getInstance(context).setUserProperty(USER_PROPERTY_SELECTED_SOURCE_PACKAGE, +- packageName); +- String className = selectedSource.flattenToShortString(); +- className = className.substring(className.indexOf('/')+1); +- if (className.length() > MAX_VALUE_LENGTH) { +- className = className.substring(className.length() - MAX_VALUE_LENGTH); +- } +- FirebaseAnalytics.getInstance(context).setUserProperty(USER_PROPERTY_SELECTED_SOURCE, +- className); +- } +- + public static ComponentName getSelectedSource(Context context) { + try (Cursor data = context.getContentResolver().query(MuzeiContract.Sources.CONTENT_URI, + new String[] {MuzeiContract.Sources.COLUMN_NAME_COMPONENT_NAME}, +diff --git a/main/src/main/java/com/google/android/apps/muzei/quicksettings/NextArtworkTileService.java b/main/src/main/java/com/google/android/apps/muzei/quicksettings/NextArtworkTileService.java +index a797676..5a78aad 100644 +--- a/main/src/main/java/com/google/android/apps/muzei/quicksettings/NextArtworkTileService.java ++++ b/main/src/main/java/com/google/android/apps/muzei/quicksettings/NextArtworkTileService.java +@@ -35,7 +35,6 @@ import com.google.android.apps.muzei.SourceManager; + import com.google.android.apps.muzei.api.MuzeiArtSource; + import com.google.android.apps.muzei.api.MuzeiContract; + import com.google.android.apps.muzei.event.WallpaperActiveStateChangedEvent; +-import com.google.firebase.analytics.FirebaseAnalytics; + + import net.nurik.roman.muzei.R; + +@@ -54,7 +53,6 @@ public class NextArtworkTileService extends TileService { + + @Override + public void onTileAdded() { +- FirebaseAnalytics.getInstance(this).logEvent("tile_next_artwork_added", null); + } + + @Override +@@ -133,8 +131,6 @@ public class NextArtworkTileService extends TileService { + return; + } + if (tile.getState() == Tile.STATE_ACTIVE) { +- FirebaseAnalytics.getInstance(NextArtworkTileService.this).logEvent( +- "tile_next_artwork_click", null); + // Active means we send the 'Next Artwork' command + SourceManager.sendAction(this, MuzeiArtSource.BUILTIN_COMMAND_ID_NEXT_ARTWORK); + } else { +@@ -142,8 +138,6 @@ public class NextArtworkTileService extends TileService { + unlockAndRun(new Runnable() { + @Override + public void run() { +- FirebaseAnalytics.getInstance(NextArtworkTileService.this).logEvent( +- "tile_next_artwork_activate", null); + try { + startActivityAndCollapse(new Intent(WallpaperManager.ACTION_CHANGE_LIVE_WALLPAPER) + .putExtra(WallpaperManager.EXTRA_LIVE_WALLPAPER_COMPONENT, +@@ -172,6 +166,5 @@ public class NextArtworkTileService extends TileService { + + @Override + public void onTileRemoved() { +- FirebaseAnalytics.getInstance(this).logEvent("tile_next_artwork_removed", null); + } + } +diff --git a/main/src/main/java/com/google/android/apps/muzei/settings/SettingsActivity.java b/main/src/main/java/com/google/android/apps/muzei/settings/SettingsActivity.java +index f24deb8..cca86d4 100644 +--- a/main/src/main/java/com/google/android/apps/muzei/settings/SettingsActivity.java ++++ b/main/src/main/java/com/google/android/apps/muzei/settings/SettingsActivity.java +@@ -44,7 +44,6 @@ import android.widget.Toast; + import com.google.android.apps.muzei.event.WallpaperActiveStateChangedEvent; + import com.google.android.apps.muzei.render.MuzeiRendererFragment; + import com.google.android.apps.muzei.util.DrawInsetsFrameLayout; +-import com.google.firebase.analytics.FirebaseAnalytics; + + import net.nurik.roman.muzei.R; + +@@ -94,7 +93,6 @@ public class SettingsActivity extends AppCompatActivity + + if (getIntent() != null && getIntent().getCategories() != null && + getIntent().getCategories().contains(Notification.INTENT_CATEGORY_NOTIFICATION_PREFERENCES)) { +- FirebaseAnalytics.getInstance(this).logEvent("notification_preferences_open", null); + mStartSection = START_SECTION_ADVANCED; + } + +@@ -224,7 +222,6 @@ public class SettingsActivity extends AppCompatActivity + public boolean onMenuItemClick(MenuItem item) { + switch (item.getItemId()) { + case R.id.action_get_more_sources: +- FirebaseAnalytics.getInstance(SettingsActivity.this).logEvent("more_sources_open", null); + try { + Intent playStoreIntent = new Intent(Intent.ACTION_VIEW, + Uri.parse("http://play.google.com/store/search?q=Muzei&c=apps")) +@@ -239,7 +236,6 @@ public class SettingsActivity extends AppCompatActivity + return true; + + case R.id.action_about: +- FirebaseAnalytics.getInstance(SettingsActivity.this).logEvent("about_open", null); + startActivity(new Intent(SettingsActivity.this, AboutActivity.class)); + return true; + } +diff --git a/main/src/main/java/com/google/android/apps/muzei/settings/SettingsChooseSourceFragment.java b/main/src/main/java/com/google/android/apps/muzei/settings/SettingsChooseSourceFragment.java +index 3ad9ef0..9a1a490 100644 +--- a/main/src/main/java/com/google/android/apps/muzei/settings/SettingsChooseSourceFragment.java ++++ b/main/src/main/java/com/google/android/apps/muzei/settings/SettingsChooseSourceFragment.java +@@ -60,7 +60,6 @@ import com.google.android.apps.muzei.api.MuzeiContract; + import com.google.android.apps.muzei.util.CheatSheet; + import com.google.android.apps.muzei.util.ObservableHorizontalScrollView; + import com.google.android.apps.muzei.util.Scrollbar; +-import com.google.firebase.analytics.FirebaseAnalytics; + + import net.nurik.roman.muzei.R; + +@@ -132,10 +131,6 @@ public class SettingsChooseSourceFragment extends Fragment implements LoaderMana + if (!(activity instanceof Callbacks)) { + throw new ClassCastException("Activity must implement fragment callbacks."); + } +- +- Bundle bundle = new Bundle(); +- bundle.putString(FirebaseAnalytics.Param.ITEM_CATEGORY, "sources"); +- FirebaseAnalytics.getInstance(getActivity()).logEvent(FirebaseAnalytics.Event.VIEW_ITEM_LIST, bundle); + } + + @Override +@@ -467,17 +462,10 @@ public class SettingsChooseSourceFragment extends Fragment implements LoaderMana + ((Callbacks) getActivity()).onRequestCloseActivity(); + } else if (source.setupActivity != null) { + Bundle bundle = new Bundle(); +- bundle.putString(FirebaseAnalytics.Param.ITEM_ID, source.componentName.flattenToShortString()); +- bundle.putString(FirebaseAnalytics.Param.ITEM_NAME, source.label); +- bundle.putString(FirebaseAnalytics.Param.ITEM_CATEGORY, "sources"); +- FirebaseAnalytics.getInstance(getActivity()).logEvent(FirebaseAnalytics.Event.VIEW_ITEM, bundle); + mCurrentInitialSetupSource = source.componentName; + launchSourceSetup(source); + } else { + Bundle bundle = new Bundle(); +- bundle.putString(FirebaseAnalytics.Param.ITEM_ID, source.componentName.flattenToShortString()); +- bundle.putString(FirebaseAnalytics.Param.CONTENT_TYPE, "sources"); +- FirebaseAnalytics.getInstance(getActivity()).logEvent(FirebaseAnalytics.Event.SELECT_CONTENT, bundle); + SourceManager.selectSource(getContext(), source.componentName); + } + } +@@ -558,9 +546,6 @@ public class SettingsChooseSourceFragment extends Fragment implements LoaderMana + if (requestCode == REQUEST_EXTENSION_SETUP) { + if (resultCode == Activity.RESULT_OK && mCurrentInitialSetupSource != null) { + Bundle bundle = new Bundle(); +- bundle.putString(FirebaseAnalytics.Param.ITEM_ID, mCurrentInitialSetupSource.flattenToShortString()); +- bundle.putString(FirebaseAnalytics.Param.CONTENT_TYPE, "sources"); +- FirebaseAnalytics.getInstance(getActivity()).logEvent(FirebaseAnalytics.Event.SELECT_CONTENT, bundle); + SourceManager.selectSource(getContext(), mCurrentInitialSetupSource); + } + +diff --git a/main/src/main/java/com/google/android/apps/muzei/wearable/NotificationOpenListenerService.java b/main/src/main/java/com/google/android/apps/muzei/wearable/NotificationOpenListenerService.java +deleted file mode 100644 +index aa55e66..0000000 +--- a/main/src/main/java/com/google/android/apps/muzei/wearable/NotificationOpenListenerService.java ++++ /dev/null +@@ -1,33 +0,0 @@ +-/* +- * Copyright 2014 Google Inc. +- * +- * 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.google.android.apps.muzei.wearable; +- +-import android.content.Intent; +-import android.content.pm.PackageManager; +- +-import com.google.android.gms.wearable.MessageEvent; +-import com.google.android.gms.wearable.WearableListenerService; +- +-public class NotificationOpenListenerService extends WearableListenerService { +- @Override +- public void onMessageReceived(MessageEvent messageEvent) { +- // Only notification/open actions trigger this WearableListenerService +- PackageManager packageManager = getPackageManager(); +- Intent mainIntent = packageManager.getLaunchIntentForPackage(getPackageName()); +- startActivity(mainIntent); +- } +-} +diff --git a/main/src/main/java/com/google/android/apps/muzei/wearable/WearableController.java b/main/src/main/java/com/google/android/apps/muzei/wearable/WearableController.java +deleted file mode 100644 +index 29fd060..0000000 +--- a/main/src/main/java/com/google/android/apps/muzei/wearable/WearableController.java ++++ /dev/null +@@ -1,124 +0,0 @@ +-/* +- * Copyright 2014 Google Inc. +- * +- * 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.google.android.apps.muzei.wearable; +- +-import android.content.ContentResolver; +-import android.content.Context; +-import android.graphics.Bitmap; +-import android.graphics.BitmapFactory; +-import android.graphics.Matrix; +-import android.support.media.ExifInterface; +-import android.util.Log; +- +-import com.google.android.apps.muzei.api.Artwork; +-import com.google.android.apps.muzei.api.MuzeiContract; +-import com.google.android.apps.muzei.render.ImageUtil; +-import com.google.android.gms.common.ConnectionResult; +-import com.google.android.gms.common.GoogleApiAvailability; +-import com.google.android.gms.common.api.GoogleApiClient; +-import com.google.android.gms.wearable.Asset; +-import com.google.android.gms.wearable.DataMap; +-import com.google.android.gms.wearable.PutDataMapRequest; +-import com.google.android.gms.wearable.Wearable; +- +-import java.io.ByteArrayOutputStream; +-import java.io.FileNotFoundException; +-import java.io.IOException; +-import java.io.InputStream; +-import java.util.concurrent.TimeUnit; +- +-/** +- * Controller for working with the Android Wear API. Also in charge of dealing with +- * Google Play Services. +- */ +-public class WearableController { +- private static final String TAG = "WearableController"; +- +- public static synchronized void updateArtwork(Context context) { +- if (ConnectionResult.SUCCESS != GoogleApiAvailability.getInstance().isGooglePlayServicesAvailable(context)) { +- return; +- } +- GoogleApiClient googleApiClient = new GoogleApiClient.Builder(context) +- .addApi(Wearable.API) +- .build(); +- ConnectionResult connectionResult = googleApiClient.blockingConnect(5, TimeUnit.SECONDS); +- if (!connectionResult.isSuccess()) { +- if (connectionResult.getErrorCode() != ConnectionResult.API_UNAVAILABLE) { +- Log.w(TAG, "onConnectionFailed: " + connectionResult); +- } +- return; +- } +- ContentResolver contentResolver = context.getContentResolver(); +- Bitmap image = null; +- try { +- BitmapFactory.Options options = new BitmapFactory.Options(); +- options.inJustDecodeBounds = true; +- BitmapFactory.decodeStream(contentResolver.openInputStream( +- MuzeiContract.Artwork.CONTENT_URI), null, options); +- options.inJustDecodeBounds = false; +- if (options.outWidth > options.outHeight) { +- options.inSampleSize = ImageUtil.calculateSampleSize(options.outHeight, 320); +- } else { +- options.inSampleSize = ImageUtil.calculateSampleSize(options.outWidth, 320); +- } +- image = BitmapFactory.decodeStream(contentResolver.openInputStream( +- MuzeiContract.Artwork.CONTENT_URI), null, options); +- } catch (FileNotFoundException e) { +- Log.e(TAG, "Unable to read artwork to update Android Wear", e); +- } +- if (image != null) { +- int rotation = getRotation(context); +- if (rotation != 0) { +- // Rotate the image so that Wear always gets a right side up image +- Matrix matrix = new Matrix(); +- matrix.postRotate(rotation); +- image = Bitmap.createBitmap(image, 0, 0, image.getWidth(), image.getHeight(), +- matrix, true); +- } +- final ByteArrayOutputStream byteStream = new ByteArrayOutputStream(); +- image.compress(Bitmap.CompressFormat.PNG, 100, byteStream); +- Asset asset = Asset.createFromBytes(byteStream.toByteArray()); +- PutDataMapRequest dataMapRequest = PutDataMapRequest.create("/artwork"); +- Artwork artwork = MuzeiContract.Artwork.getCurrentArtwork(context); +- dataMapRequest.getDataMap().putDataMap("artwork", DataMap.fromBundle(artwork.toBundle())); +- dataMapRequest.getDataMap().putAsset("image", asset); +- Wearable.DataApi.putDataItem(googleApiClient, dataMapRequest.asPutDataRequest().setUrgent()).await(); +- } +- googleApiClient.disconnect(); +- } +- +- private static int getRotation(Context context) { +- ContentResolver contentResolver = context.getContentResolver(); +- int rotation = 0; +- try (InputStream in = contentResolver.openInputStream( +- MuzeiContract.Artwork.CONTENT_URI)) { +- if (in == null) { +- return 0; +- } +- ExifInterface exifInterface = new ExifInterface(in); +- int orientation = exifInterface.getAttributeInt( +- ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL); +- switch (orientation) { +- case ExifInterface.ORIENTATION_ROTATE_90: rotation = 90; break; +- case ExifInterface.ORIENTATION_ROTATE_180: rotation = 180; break; +- case ExifInterface.ORIENTATION_ROTATE_270: rotation = 270; break; +- } +- } catch (IOException|NumberFormatException|StackOverflowError ignored) { +- } +- return rotation; +- } +-} +diff --git a/settings.gradle b/settings.gradle +index eac0130..37a120e 100644 +--- a/settings.gradle ++++ b/settings.gradle +@@ -1 +1 @@ +-include ':api', ':android-client-common', ':source-featured-art', ':source-gallery', ':main', ':wearable', ':example-source-500px', 'example-watchface' ++include ':api', ':android-client-common', ':source-featured-art', ':source-gallery', ':main', ':example-source-500px'